使用Topshelf快速搭建Windows服务

创建一个windows服务用于同步SqlServer数据到Elasticsearch

新建elasticsearch索引

PUT:http://localhost:9200/index_singer/

{
  "settings": {
    "number_of_shards": 5,
    "number_of_replicas": 1
  },
  "mappings": {
    "singer_index": {
      "properties": {
        "id": {
          "type": "long"
        },
        "SerialNumber": {
          "type": "integer"
        },
        "RealName": {
          "type": "string"
        },
        "NickName": {
          "type": "string"
        },
        "Nationality": {
          "type": "string"
        },
        "Birthplace": {
          "type": "string"
        },
        "Birthday": {
          "format": "dateOptionalTime",
          "type": "date"
        },
        "Constellation": {
          "type": "string"
        },
        "BriefIntroduction": {
          "type": "string",
          "fields": {
            "no": {
              "index": "not_analyzed",
              "type": "string"
            },
            "en": {
              "analyzer": "english",
              "type": "string"
            },
            "cn": {
              "analyzer": "ik",
              "type": "string"
            }
          }
        },
        "IsApprove": {
          "type": "boolean"
        },
        "CreateBy": {
          "type": "string"
        },
        "CreateDate": {
          "format": "dateOptionalTime",
          "type": "date"
        },
        "ModifyBy": {
          "type": "string"
        },
        "ModifyDate": {
          "format": "dateOptionalTime",
          "type": "date"
        }
      }
    }
  },
  "aliases": {
    "singer": { }
  }
}

1、创建控制台程序

2、安装Topshelf组件

   Install-Package Topshelf

Program

using EsDataImporter.Worker;
using Topshelf;

namespace EsDataImporter
{
    public class Program
    {
        public static void Main()
        {
            HostFactory.Run(x =>
            {
                x.Service<DataWorker>(s =>
                {
                    s.ConstructUsing(name => new DataWorker());
                    //服务启动执行方法
                    s.WhenStarted(tc => tc.Start());
                    //服务结束执行方法
                    s.WhenStopped(tc => tc.Stop());
                });
                x.RunAsLocalSystem();
                x.SetDescription("Data Synchronism For Elasticsearch");
                x.SetDisplayName("EsDataSync");
                x.SetServiceName("EsDataSync");
            });
        }
    }
}

安装:EsDataImporter.exe install

启动:EsDataImporter.exe start

卸载:EsDataImporter.exe uninstall

DataWorker

using EsDataImporter.Common;
using EsDataImporter.Job;
using Quartz;
using System.Threading.Tasks;

namespace EsDataImporter.Worker
{
    public class DataWorker
    {
        public DataWorker()
        {
        }
        /// <summary>
        /// windows Service Start执行
        /// </summary>
        public void Start()
        {
            Task.Factory.StartNew(() =>
            {
                if (!CommonHelper.scheduler.IsStarted)
                {
                    //创建一个作业
                    IJobDetail singerJob = JobBuilder.Create<ExIndexSinger>()
                        .WithIdentity("sJob")
                        .Build();
                    ITrigger singerTrigger = TriggerBuilder.Create()
                                                .WithIdentity("sTrigger")
                                                .StartNow()                             //现在开始
                                                .WithSimpleSchedule(x => x              //触发时间,24小时一次。
                                                    .WithIntervalInSeconds(5)           //5s执行一次
                                                    .RepeatForever())                   //不间断重复执行
                                                .Build();
                    CommonHelper.scheduler.ScheduleJob(singerJob, singerTrigger);       //把作业,触发器加入调度器。
                    CommonHelper.scheduler.Start();
                }
            });
        }

        /// <summary>
        /// windows Service Stop执行
        /// </summary>
        public void Stop()
        {

        }
    }
}

CommonHelper

using Quartz;
using Quartz.Impl;
using ServiceStack.Orm.Extension.Imples;
using ServiceStack.Orm.Extension.Interface;
using ServiceStack.OrmLite;
using System.Configuration;

namespace EsDataImporter.Common
{
    public static class CommonHelper
    {
        /// <summary>
        /// Orm client
        /// </summary>
        public static IOrmClient dbClient = dbClient = new OrmClient(ConfigurationManager.ConnectionStrings["mssql"].ConnectionString, SqlServerDialect.Provider);
        /// <summary>
        /// 任务调度器实例
        /// </summary>
        public static IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
    }
}

SqlServer实体模型

using System;
using ServiceStack.DataAnnotations;
using ServiceStack.Model;
using ServiceStack;
using ServiceStack.Orm.Extension.Interface;

namespace Datebase.Entity
{
    public partial class T_Singer : IDBEntity
    {
        [Required]
        [PrimaryKey]
        public long ID { get; set; }
        public int? SerialNumber { get; set; }
        public string RealName { get; set; }
        public string NickName { get; set; }
        public string Nationality { get; set; }
        public string Birthplace { get; set; }
        public DateTime? Birthday { get; set; }
        public string Constellation { get; set; }
        public string BriefIntroduction { get; set; }
        public bool? IsApprove { get; set; }
        public string CreateBy { get; set; }
        public DateTime? CreateDate { get; set; }
        public string ModifyBy { get; set; }
        public DateTime? ModifyDate { get; set; }
    }
}

Elasticsearch实体模型

using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EsDataImporter.Model
{
    public class ix_singer
    {
        /// <summary>
        /// 主键ID
        /// </summary>
        public long ID { get; set; }
        /// <summary>
        /// 歌手序号
        /// </summary>
        public int? SerialNumber { get; set; }
        /// <summary>
        /// 真实姓名
        /// </summary>
        public string RealName { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        public string NickName { get; set; }
        /// <summary>
        /// 国籍
        /// </summary>
        public string Nationality { get; set; }
        /// <summary>
        /// 出生地
        /// </summary>
        public string Birthplace { get; set; }
        /// <summary>
        /// 生日
        /// </summary>
        public DateTime? Birthday { get; set; }
        /// <summary>
        /// 星座
        /// </summary>
        public string Constellation { get; set; }
        /// <summary>
        /// 简介
        /// </summary>
        public string BriefIntroduction { get; set; }
        /// <summary>
        /// 有效性
        /// </summary>
        public bool? IsApprove { get; set; }
        /// <summary>
        /// 创建人
        /// </summary>
        public string CreateBy { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime? CreateDate { get; set; }
        /// <summary>
        /// 修改人
        /// </summary>
        public string ModifyBy { get; set; }
        /// <summary>
        /// 修改时间
        /// </summary>
        public DateTime? ModifyDate { get; set; }
    }
}

ExIndexSinger:定时任务

using Datebase.Entity;
using EmitMapper;
using EsDataImporter.Common;
using EsDataImporter.Model;
using Nest;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EsDataImporter.Job
{
    public class ExIndexSinger : IJob
    {
        string searchAddress = "http://127.0.0.1:9200/";    //服务地址
        string singerIndex = "singer_index";                //索引名称
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                JobIndex();
            }
            catch (Exception x)
            {
                //日志
                NLog.LogManager.GetCurrentClassLogger().Error(x.ToString());
            }
        }

        #region 歌手信息索引同步方法

        /// <summary>
        /// 职位索引
        /// </summary>
        private void JobIndex()
        {
            var node = new Uri(searchAddress);
            var settings = new ConnectionSettings(node);
            var client = new ElasticClient(settings);
            var ck = client.IndexExists(singerIndex);
            //文档修改时间-数据库中的新创建文档修改时间就是创建时间
            DateTime mtime = new DateTime(1970, 1, 1);
            if (ck.Exists)
            {
                //从es中查询出文档的最后修改时间
                var response = client.Search<ix_singer>(s =>
                                s.Aggregations(a => a
                                .Max("MaxModifyDate", m => m
                                    .Field(p => p.ModifyDate)
                                )
                            ).From(0).Size(1)
                        );

                var maxModifyDate = response.Aggs.Max("MaxModifyDate");
                //文档的最新修改时间
                mtime = mtime.AddMilliseconds(maxModifyDate.Value ?? 0);
            }
            else
            {
                //创建该索引
                var createIndexResult = client.CreateIndex(singerIndex);
                var mapResult = client.Map<ix_singer>(e => e.AutoMap());
            }
            var result = QuerySinger(mtime);
            //使用EmitMapper映射实体对象
            ObjectsMapper<T_Singer, ix_singer> mapper = ObjectMapperManager.DefaultInstance.GetMapper<T_Singer, ix_singer>();
            var singers = result.Select(e => mapper.Map(e));
            if (result.Any())
            {
                //将关系型数据库中的数据同步到es服务中
                var response = client.IndexMany<ix_singer>(singers, singerIndex);
                NLog.LogManager.GetCurrentClassLogger().Error(singers.Count());
            }
        }

        #endregion

        #region 数据查询方法

        /// <summary>
        /// 查询出新增和修改的歌手的信息
        /// </summary>
        private List<T_Singer> QuerySinger(DateTime modifyDate)
        {
            var expre = CommonHelper.dbClient.From<T_Singer>();
            expre.And(e => e.ModifyDate > modifyDate);
            return CommonHelper.dbClient.Select(expre);
        }

        #endregion
    }
}

时间: 2024-10-20 03:20:05

使用Topshelf快速搭建Windows服务的相关文章

centos 使用sshfs快速搭建文件共享服务

centos 使用sshfs快速搭建文件共享服务 看了很多教程都写的不够完整所以自己根据实际操作找遇到的坑共享一下给大家 共享文件服务器必须打开ssh服务器 实例:IP192.168.7.50 yum -y install epel-release # 安装epel 源码 yum -y install fuse-sshfs # 安装sshfs  sshfs -o allow_other,nonempty [email protected]:/opt/ /opt/http 指定密钥文件 sshfs

Ubuntu Linux下快速搭建Samba服务

引用:http://www.linuxidc.com/Linux/2016-03/129195.htm Samba服务对于从事Linux开发从业人员来说并不陌生,现在也有Windows版本了,当我们在开发Linux驱动或者应用的时候,一般都输需要个Linux开发环境.对于大公司来说有个服务器可供程序员们公共使用,但对于小公司来说一般是在虚拟机里转个Linux开发环境,也很少用实体机来装Linux的,当然也有例外.这是时候往往涉及到Windows和Linux之间文件交互的问题,我现在用的最多的就是

记录一下:使用 python -m SimpleHTTPServer 快速搭建http服务

在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer. 我们可以很简单的使用  python -m SimpleHTTPServer 快速搭建一个http服务,提供一个文件浏览的web服务. 命令如下: python -m SimpleHTTPServer 8000 使用上面的命令可以把当前目录发布到8000端口. 但是这条命令是当前运行的,不是后台运行的,也就是说如果Ctrl + C,则该端口就会关闭. python -

快速搭建samba服务

如何在UNIX主机和windows主机共享数据呢?搭建FTP服务是一种,但是FTP能够很方便的上传下载数据,但是如果想修改数据就会比较麻烦了,这时你需要先把文件下载下来,修改以后再上传上去,这种办法很麻烦,不符合我们的需要. 使用NFS服务呢?NFS服务器共享一个目录,然后NFS客户端挂载此目录,若客户端有rwx权限,很轻松的便可以修改数据,而且修改后数据在各主机之间同时可以看到.但遗憾的是NFS只能在类UNIX主机之间使用,不能跨平台.而windows上的CIFS(Common Interne

快速搭建FTP服务

Linux下ftp服务可以通过搭建vsftpd服务来实现,以CentOS为例,首先查看系统中是否安装了vsftpd,可以通过执行命令 rpm -qa | grep vsftpd 来查看是否安装相应的包,如果没有安装那么可以执行 yum -yinstall vsftpd 来安装,安装之后首先创建ftp用户,比如ftp_test,命令如下: useradd -s /sbin/nologin -d /home/ftp_test ftp_test 目录尽量不要选择根目录下,这里是/home/ftp_te

十分钟快速搭建wordpress服务

wordpress服务需要对应的mysql数据库服务,安装wordpress之前需要先搭建好数据库服务.现在都流行基于拉取镜像启动docker容器方式提供服务,因此需要一台能上外网的1核1G的机器,在机器上安装好docker. 1.安装mysql数据库 a. 拉取mysql镜像 docker pull mysql:5.7 b.启动mysql容器服务 docker run --name mysql-db -v /data/mysql:/var/lib/mysql -d -e MYSQL_ROOT_

使用Docker快速搭建sftp服务

环境: docker环境 如果是centos7系统,没有安装docker,直接使用以下命令安装 yum -y install docker systemctl start docker.service 镜像拉取: PS:不拉取也可以,在docker run的时候检测到没有镜像会自动拉取 docker pull docker.io/atmoz/sftp 最简单的使用docker搭建sftp实例: docker run -p 22:22 -d atmoz/sftp foo:pass:::upload

快速搭建多线程Windows服务解决方案

一.引言 在软件开发过程中windows服务有的时候非常有用,用于同步数据,发送邮件,宿主WF引擎服务等,但是快速搭建一个好用多线程进行多任务处理的程序往往是一个项目必须考虑的问题.自己在项目中也经常碰到类似的问题,但是一直没有做过这方面总结,每次需要相关windows服务,也重头写一次.自己几乎没有写博客的习惯,前不久看到博客园中有篇关于windows服务的框架写的非常好(抱歉,当时看完以后忘记收藏),感觉自己这些年对它也有一定的认识,但是很少拿出来和大家分享.其实大家都知道通过分享才能找到问

快速搭建 SpringCloud 微服务开发环境的脚手架

本文适合有 SpringBoot 和 SpringCloud 基础知识的人群,跟着本文可使用和快速搭建 SpringCloud 项目. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一款基于 SpringCloud2.1 的微服务开发脚手开源项目——SpringCloud 项目源码地址:https://github.com/zhoutaoo/SpringCloud 一.微服务的简介 微服务是可以独立部署.水平扩展.独立访问的服务单元.