zoukankan      html  css  js  c++  java
  • .NET Core部署Windows服务

    创建

    首先你要确保你已经安装了.NET Core 3.0或以上版本

    老版本的Windows服务请看 这篇文章

    • 使用命令行创建:  dotnet new worker 
    • 使用Visual Studio创建

    中文版:

     英文版:

     

    创建的新项目包含两个文件。其中 Program.cs 文件是应用的启动程序。另外一个文件是 Worker.cs 文件,你可以在这个文件编写你的业务代码。

    这看起来应该是相当的容易,但是为这个程序添加额外的并行后台服务,你还需要添加一个类,并让它继承 BackgroundService 类:

    public class MyNewBackgroundWorker : BackgroundService
    {    
        protected override Task ExecuteAsync(CancellationToken stoppingToken)    
        {        
            //Do something.     
        }
     }

    然后在 Program.cs 中,我们要做的只是把当前的Worker注册到服务集合(Service Collection)中即可。

    .ConfigureServices((hostContext, services) =>
    {
        services.AddHostedService<Worker>();
        services.AddHostedService<MyNewBackgroundWorker>();
    });

    实际上作为“后台服务”任务的运行程序, AddHostedService 方法已经在框架中存在了很长时间了。在之前我们已经完成的一篇关于ASP.NET Core托管服务的文章, 但是在当时场景中,我们托管是是整个应用,而非一个在你应用程序幕后运行的东西。

    优化系统的 Worker.cs ,代码执行顺序是冲上往下依次执行的(程序开始-停止)

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    
    namespace WorkerService
    {
        public class Worker : BackgroundService
        {
            private readonly ILogger<Worker> _logger;
    
            public Worker(ILogger<Worker> logger)
            {
                _logger = logger;
            }
    
            public override Task StartAsync(CancellationToken cancellationToken)
            {
                _logger.LogInformation($"Worker started at: {DateTime.Now}");
                return base.StartAsync(cancellationToken);
            }
    
            protected override async Task ExecuteAsync(CancellationToken stoppingToken)
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                    await Task.Delay(1000, stoppingToken);
                }
            }
    
            public override Task StopAsync(CancellationToken cancellationToken)
            {
                _logger.LogError($"Worker stopped at: {DateTime.Now}");
    
                return base.StopAsync(cancellationToken);
            }
    
            public override void Dispose()
            {
                _logger.LogInformation($"Worker disposed at: {DateTime.Now}");
    
                base.Dispose();
            }
        }
    }
    View Code

    部署Windows服务

    需要引用  Microsoft.Extensions.Hosting.WindowsServices  Neget 包

    Install-Package Microsoft.Extensions.Hosting.WindowsServices

    修改 Program.cs 文件,添加 UseWindowsService() 方法调用

    public static IHostBuilder CreateHostBuilder(string[] args) => 
        Host.CreateDefaultBuilder(args)    
            .ConfigureServices((hostContext, services) =>    
            {        
                services.AddHostedService<Worker>();   
             })
             .UseWindowsService();

    这样代码部分就完成了。

    然后使用 cmd 命令把我们发布后的程序代码部署成Windows服务,需要使用管理员权限运行CMD

    借助 sc.exe 工具。sc.exe是帮助开发部署 WindowsNT 服务的工具,路径: C:WindowsSystem32sc.exe。这个网上教程一大堆,可以自行了解,这里不多介绍。

    相关命令:

    下面的 ServiceName 是自定义的,可以自行修改

    ## 创建服务
    sc create ServiceName  BinPath=E:WorkCodeWindowsServiceDemoWorkerServiceinDebug
    etcoreapp3.0WorkerService.exe
    
    ## 启动服务
    sc start ServiceName
    
    ## 停止服务
    sc stop ServiceName
    
    ## 删除服务
    sc delete ServiceName
    
    
    ## 添加服务描述
    sc description ServiceName "描述"
    
    ## 改变服务的启动方式 手动/自动/禁用 
    sc config ServiceName start= demand/auto/disabled  

    install.bat

    set serviceName=ServiceName
    set serviceFilePath=E:WorkCodeWindowsServiceDemoWorkerServiceinDebug
    etcoreapp3.0WorkerService.exe
    set serviceDescription=服务描述
    
    sc create %serviceName%  BinPath=%serviceFilePath%
    sc config %serviceName%    start=auto  
    sc description %serviceName%  %serviceDescription%
    sc start  %serviceName%
    pause

    unstall.bat

    set serviceName=ServiceName
    
    sc stop   %serviceName% 
    sc delete %serviceName% 
    
    pause

    最后使用管理员权限运行 install.bat

    查看下服务面板

    以上是参考 这边文章 编写的。

    部署Linux服务

    环境:一台全新的Centos 7.7.1908 系统 

    安装 .net core相关环境

    参考:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-package-manager-centos7

    注册 Microsoft 密钥和源:  

     sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

    安装 .NET Core SDK:

    sudo yum install dotnet-sdk-3.0  -y

    安装完成之后可以输入 dotnet --version 查看是否可以返回对应版本 

    修改代码

    程序代码需要引用 Microsoft.Extensions.Hosting.Systemd  Neget包

    Install-Package Microsoft.Extensions.Hosting.Systemd

    修改  Program.cs  文件,添加  UseSystemd()  方法调用,可以和 UseWindowsService() 共存

            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureServices((hostContext, services) =>
                    {
                        services.AddHostedService<Worker>();
                    })
                      .UseWindowsService()
                      .UseSystemd();

    然后把发布文件移至linux系统

    部署服务

    linux的服务是通过systemd守护进程部署的。现在在系统中我们有了一个发布后的应用程序,我们需要为systemd创建配置文件部署服务。步骤如下:

    创建一个.service文件(我们要部署服务,因此需要.service文件),填入以下内容。可以在Linux中直接创建或者通过windows创建然后拷贝至linux。 

    参考链接

    [Unit]
    Description= my test app
    [Service] Type
    =notify ExecStart=/usr/bin/dotnet /home/demo/WorkerService.dll [Install] WantedBy=multi-user.target

    Description:描述,看个人需要是否添加。不需要可以去掉。只留下 [Service] 和 [Install]
    Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
    ExecStart:启动当前服务的命令,程序如何启动,第一个路径是固定路径。第二个路径是应用程序的dll路径(可以自定义)
    WantedBy:表示该服务所在的 Target服务组, multi-user.target,表示多用户命令行状态。

    把 .service文件移动至  /etc/systemd/system/   固定目录下,假设自定义文件名称为:testapp.service(如果使用其他名称,请更改testapp)

      

    使用systemctl命令重新加载新的配置文件

    sudo systemctl daemon-reload

    查看相关服务状态

    sudo systemctl status testapp

    您应该看到类似以下的内容: 

     这表明您已注册的新服务已禁用,我们可以通过运行以下命令来启动我们的服务:

    sudo systemctl start testapp.service

    重新运行 sudo systemctl status testapp  查看服务状态显示已激活正在运行中

     设置服务开机自启

    sudo systemctl enable testapp.service

    到此我们的服务已经完整的部署到了linux系统中

    现在我们有一个运行了systemd的应用程序,我们可以看看日志记录集成。使用systemd的好处之一是可以使用journalctl访问的集中式日志记录系统。

    首先,我们可以使用journalctl(访问日志的命令)查看服务日志:

    sudo journalctl -u testapp

     可以看到我们的程序正在运行,可以使用 ↑↓ ← →查看日志内容。或者使用grep搜索。q  键退出

    卸载自定义服务

    servicename=testapp.service
    
    systemctl stop $servicename
    systemctl disable $servicename
    rm -rf /etc/systemd/system/$servicename
    rm -rf /etc/systemd/system/$servicename symlinks that might be related
    systemctl daemon-reload
    systemctl reset-failed

    相关链接

    部署Windows服务相关链接:

    https://www.cnblogs.com/lwqlun/p/12038062.html

    https://devblogs.microsoft.com/aspnet/net-core-workers-as-windows-services/

    https://www.cnblogs.com/Rwing/p/net-core-workers-as-windows-services.html

    自定义安装服务相关配置相关链接:
    http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
    https://www.cnblogs.com/jhxxb/p/10654554.html

     

    systemd命令相关链接:

    https://www.cnblogs.com/tsdxdx/p/7288490.html

    http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html

    https://www.cnblogs.com/zyh121344305/p/8677015.html

    https://www.cnblogs.com/jhxxb/p/10654554.html

     部署Linux服务相关链接:

    https://devblogs.microsoft.com/dotnet/net-core-and-systemd/

    https://stackoverflow.com/questions/51589504/asp-net-core-2-0-unable-to-start-service-on-debian

     源码地址:https://github.com/RainFate/WindowsServiceDemo/tree/Init/WorkerService

  • 相关阅读:
    我画着图,FluentAPI 她自己就生成了
    寻找性能更优秀的不可变小字典
    寻找性能更优秀的动态 Getter 和 Setter 方案
    数据治理方案技术调研 Atlas VS Datahub VS Amundsen
    数据库读写分离这个坑,你应该踩过吧?
    写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理
    年轻人不讲武德,竟然重构出这么优雅后台 API 接口
    贞炸了!上线之后,消息收不到了!
    一笔订单,但是误付了两笔钱!这种重复付款异常到底该如何解决?
    自动化运维工具之Puppet master/agent模型、站点清单和puppet多环境设定
  • 原文地址:https://www.cnblogs.com/RainFate/p/12095793.html
Copyright © 2011-2022 走看看