NET 5 Topshelf 或者WorkerServices搭建 Windows/Linux 服务
参考文章https://www.cnblogs.com/RainFate/p/12095793.html
Topshelf
Topshelf 是一个用来部署基于.NET Framework 开发的服务的框架。简化服务创建于部署过程,并且支持控制台应用程序部署为服务。本文基于 .net core 控制台应用程序部署为服务(.net Framework 可用)。
第一步:创建名为 TopshelfDemo 的控制台应用程序。
第二步:通过 Nuget 安装 Topshelf 包。
第三步:Toshelf 配置,代码并不多下面都有注释。
using System; using Topshelf; namespace TopshelfDemo { class Program { static void Main(string[] args) { try { // 配置和运行宿主服务 HostFactory.Run(x => //1 { x.Service<Service>(s => //2 { // 指定服务类型。这里设置为 Service s.ConstructUsing(name => new Service()); //3 // 当服务启动后执行什么 s.WhenStarted(tc => tc.Start()); //4 // 当服务停止后执行什么 s.WhenStopped(tc => tc.Stop()); //5 }); // 服务用本地系统账号来运行 x.RunAsLocalSystem(); //6 // 服务描述信息 x.SetDescription("我的项目服务"); //7 // 服务显示名称 x.SetDisplayName("MyProjectServiceShowName"); //8 // 服务名称 x.SetServiceName("MyProjectService"); //9 }); } catch (Exception ex) { Console.WriteLine(ex); } } } public class Service { public void Start() { //To do something } public void Stop() { //To do something } } }
第四步:安装服务
确保项目正常生成,然后通过管理员权限打开 cmd 命令窗口,找到项目所在的 Debug 目录,输入命令:TopshelfDemo.exe install。
如果是使用 .net core 的小伙伴你会发现 Debug下压根没有 TopshelfDemo.exe ,这不是扯淡呢么,别急往下看。
由于 .net core 依赖 runtimes 所以我们需要发布以下程序,并且选择独立项目就ok啦。
这时你在布后的路径下就可以找到 TopshelfDemo.exe 啦。
这时服务就安装完毕了,我们可以通过 Windows 服务中查看。
删除服务命令:TopshelfDemo.exe uninstall
也可以通过 sc delete MyProjectService 进行删除
Worker Service
ASP.NET Core 3增加了一个非常有意思的功能Worker Service.他是一个ASP.NET Core模板,他允许我们创建托管长期的运行的后台服务,这些服务具体实现IHostedService接口的后台任务逻辑,他被成为"托管服务".同时他们可以部署到windows中Windows服务,以及Linux守护程序.
创建一个托管服务
您需要在您的环境中安装Visual Studio 2019和.NET Core 3.0。
首先,您需要创建一个新项目,并选择下图所示的工作流程模板:
Program.cs:
public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }); }
Worker:
BackgroundService是实现了IHostedService的基类.调用 ExecuteAsync(CancellationToken) 来运行后台服务。实现返回一个Task,其表示后台服务整个生存期.在 ExeuteAsync(例如通过调用await)之前,不会启动任何其他服务.避免在ExecuteAsync中执行长时间的阻塞初始化. StopAsync(CancellationToekn) 中的主机块等待完成ExecuteAsync。
调用 IHostedService.StopAsync 时,将触发取消令牌。 当激发取消令牌以便正常关闭服务时,ExecuteAsync 的实现应立即完成。 否则,服务将在关闭超时后不正常关闭。
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WorkerServiceDemo { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } public override async Task StartAsync(CancellationToken cancellationToken) { await base.StartAsync(cancellationToken); } public override async Task StopAsync(CancellationToken cancellationToken) { await base.StopAsync(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 void Dispose() { } } }
已使用AddHostedService扩展方法在 IHostBuilder.ConfigureServices(Program.cs)中注册该服务。
services.AddHostedService<Worker>();
WorkerServices部署到Windows服务
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace WorkerServiceDemo { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }).UseWindowsService(); ; } } }
现在我们可以部署我们的windows服务了。
发布方式
- 使用sc.exe工具
- 直接部署exe文件
发布Windows服务
dotnet restore
dotnet publish
sc.exe部署
sc.exe create DemoWorker binpath= publish\xxxx.exe
sc.exe start WorkerServicesName
部署exe文件
WorkerServicesName.exe install
WorkerServicesName.exe start
使用sc.exe停止和删除
sc.exe stop WorkerServicesName
sc.exe delete WorkerServicesName
非sc.exe停止和删除
WorkerServicesName stop
WorkerServicesName uninstall
在Linux设置守护程序
将UseSystemd()添加上。
public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }).UseSystemd(); }
在Linux上设置为守护程序。
Reference
https://github.com/hueifeng/BlogSample/tree/master/src/WorkerServiceDemo