前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >打造跨平台.NET Core后台服务

打造跨平台.NET Core后台服务

作者头像
梁规晓
发布2020-11-05 10:40:29
9780
发布2020-11-05 10:40:29
举报
文章被收录于专栏:DotNet程序园DotNet程序园

续之前讲的在TopShelf上部署ASP.NET Core程序,作为后台服务运行,自从.NET Core 3.0出现以后,出现了自带的Generic Host,使得自托管服务变为可能。

这种方式和TopShelf方式一样,可以直接F5进行服务的调试,也为跨平台后台服务编写提供了一种新的方案。

创建服务

以VS2019为例,确保安装了.NET CORE 3.0以上的SDK,新建项目,在项目模板里面可以找到Worker Service模板,创建后,vs已经帮我们创建了Program.cs和Worker.cs两个文件。

在Program.cs中

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceTest
{
public class Program
    {
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>();
        });
        }
    }
}

可以发现,配置的方式和ASP.NET CORE的方式基本一样一样的,使用了内置的DI容器。那我们同样可以使用AddSingleton等方法进行其他逻辑的注入,也可以添加多个服务任务。

而Worker类已经写了好一个范例,其中有一个ExecuteAsync方法,可以直接执行后台任务。这个时候,直接F5就可以正常运行了,自带了一个显示当前时间的小程序。

跨平台支持

虽然程序可以正常执行,但是还不能正常部署为服务,需要依据平台添加对应的nuget包:

  • windows服务,需要添加:
代码语言:javascript
复制
Install-Package Microsoft.Extensions.Hosting.WindowsServices
  • Linux服务,需要添加:
代码语言:javascript
复制
Install-Package Microsoft.Extensions.Hosting.Systemd

如果想实现一套程序多处运行,那么直接同时安装两个package就可以了。接下来在CreateHostBuilder中,添加UseWindowsService()和UseSystemd()。

代码语言:javascript
复制
public static IHostBuilder CreateHostBuilder(string[] args)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
return Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            }).UseWindowsService();
    }
else
    {
return Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            }).UseSystemd();
    }
}

这里使用到了.NET Core判断平台的一个函数:IsOSPlatform,可以判断是否在Windows平台运行,并进行分别调用。

部署

编译完成之后,找到生成的exe文件路径。

Windows下部署

管理员下运行cmd/powershell,执行

代码语言:javascript
复制
sc.exe create WorkerServiceTest binPath=C:\Users\source\repos\WorkerServiceTest\WorkerServiceTest\bin\Debug\netcoreapp3.1\WorkerServiceTest.exe

提示CreateService 成功即安装成功了,可以输入下面的命令运行服务。

代码语言:javascript
复制
sc.exe start WorkerServiceTest

sc.exe负责管理服务,具体配置启动方式和删除,可以查看命令的帮助。另外,友情提醒,如果是在powershell中,不要省略这个.exe,sc有别的用处...

Linux下部署

将整个程序文件夹传输到Linux文件夹下,我这边使用的是CentOS 8。新建一个运行服务的用户:

代码语言:javascript
复制
useradd -m dotnetuser -p dotnetpass

转到/etc/systemd/system文件夹,建立一个WorkerServiceTest.service的文件,这个WorkerServiceTest是你的服务名称。

输入以下内容并保存(systemd配置文件):

代码语言:javascript
复制
[Unit]
Description=WorkerServiceTest

[Service]
ExecStart=dotnet /bin/dotnet/WorkerServiceTest.dll
WorkingDirectory=/bin/dotnet/
User=dotnetuser
Group=dotnetuser
Restart=on-failure
SyslogIdentifier=WorkerServiceTest
PrivateTmp=true

[Install]
WantedBy=multi-user.target

注意,你需要已经安装有dotnet runtime 3.0以上版本才可以。

可以使用以下命令进行安

代码语言:javascript
复制
yum install dotnet-runtime-3.1

接下来是配置服务和启动服务

代码语言:javascript
复制
#重载配置
systemctl daemon-reload
#设置服务自动启动
systemctl enable WorkerServiceTest.service 
#运行服务
systemctl start WorkerServiceTest.service
#查询服务状态
systemctl status WorkerServiceTest.service

然后可以发现,程序可以正常运行。

补充

作为服务,应该要提供一些状态用于外部监测,在Worker.cs中,Worker类可以重写StartAsyncStopAsync方法,提供服务启动和停止的信息,但是windows提供的服务失败后动作等功能都找不到配置的地方,可能这就是局限吧。

总结

一次编写,处处运行,对于后台服务也是如此,很简洁。但是暂时手上没有mac电脑,也不知道mac上面有没有对应的解决方案。可能TopShelf的mono模式可以支持吧。

比较TopShelf模式

总体讲,相较于TopShelf的方式,Service Worker方式有利有弊。

优点:

  1. 在相同的框架(.NET CORE 3.0+)下支持跨平台,支持linux服务的systemctl管理,topshelf在linux下需要mono。
  2. 配置方式和ASP.NET CORE相似度极高,基本上可以无缝切换。

缺点:

  1. 不支持TopSelf的自带命令install/start/uninstall等命令,依然需要sc进行部署,比较麻烦。
  2. 不支持windows的很多服务管理特性(比如Pause,依赖管理)。
  3. 只支持.NET CORE 3.0以后的框架,不支持.NET FRAMEWORK和早期版本的.NET CORE。

参考资料

代码语言:javascript
复制
https://devblogs.microsoft.com/aspnet/net-core-workers-as-windows-services/
https://devblogs.microsoft.com/dotnet/net-core-and-systemd/
https://docs.microsoft.com/en-us/dotnet/core/extensions/generic-host
https://dejanstojanovic.net/aspnet/2018/june/setting-up-net-core-servicedaemon-on-linux-os/
https://dotnetcoretutorials.com/2019/12/07/creating-windows-services-in-net-core-part-3-the-net-core-worker-way/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet程序园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建服务
  • 跨平台支持
  • 部署
    • Windows下部署
      • Linux下部署
      • 补充
      • 总结
      • 比较TopShelf模式
      • 参考资料
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档