使用.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(); } } }
部署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