1. 程式人生 > >使用.NET Core建立部署Windows服務

使用.NET Core建立部署Windows服務

建立

首先你要確保你已經安裝了.NET Core 3.0或以上版本。

 

  • 使用命令列建立:  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:\Windows\System32\sc.exe。這個網上教程一大堆,可以自行了解,這裡不多介紹。

 

相關命令:

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

## 建立服務
sc create ServiceName  BinPath=E:\Work\Code\WindowsServiceDemo\WorkerService\bin\Debug\netcoreapp3.0\WorkerService.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:\Work\Code\WindowsServiceDemo\WorkerService\bin\Debug\netcoreapp3.0\WorkerService.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 退出

 

相關連結

 

部署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-de