当前位置: 首页 > 科技观察

.NET Worker Service 部署到 Linux 作为 Systemd Service 运行

时间:2023-03-12 18:50:21 科技观察

.NETWorkerService部署到Linux,作为SystemdService运行本文转载请联系技术翻译站公众号。今天我将继续介绍如何在Linux上部署WorkerService并将其作为SystemdService运行。我想在这篇文章中涵盖的内容包括:作为Linux控制台程序运行作为Systemd服务运行启动时自动运行,查看日志信息创建项目并发布§下载WorkerService源码我将基于WorkerService进行修改上一篇文章中的源码,如果你安装了git,可以使用如下命令获取:gitclonegit@github.com:ITTranslate/WorkerServiceAsWindowsService.git然后,使用VisualStudioCode打开这个项目并编译,确保一切正常:dotnetbuild§DeleteunusedDependencies从上一篇文章中删除Windows服务的依赖包:gitclonegit@github.com:ITTranslate/WorkerServiceAsWindowsService.git然后,删除Program.cs中的.UseWindowsService()方法调用。§修改配置文件打开配置文件appsettings.json,将日志文件保存路径中的\修改为/,其他不要做任何改动。{"Name":"RollingFile","Args":{"pathFormat":"Logs/{Hour}.log","outputTemplate":"{Timestamp:o}[{Level:u3}]({MachineName}/{ProcessId}/{ProcessName}/{ThreadId}){Message}{NewLine}{Exception}"}},{"Name":"SQLite","Args":{"sqliteDbPath":"Logs/log.db""tableName":"Logs","maxDatabaseSize":1,"rollOver":true}}这是因为Windows用反斜杠\表示目录,而Linux用正斜杠/表示目录。如果不修改保存路径,你会看到日志以一个别扭的文件名保存,如下:'Logs\2021061715.log''Logs\log.db'§Publisher运行dotnetpublish命令发布应用及其对文件夹的依赖性。dotnetpublish-cRelease-rlinux-x64-oc:\test\workerpub\linux我这里使用-rlinux-x64参数指定发布一个独立部署在Linux系统上的应用。命令完成运行后,您将在C:\test\workerpub\linux文件夹中看到Linux系统的可执行文件及其所有依赖项。作为Linux控制台程序运行将文件夹C:\test\workerpub\linux下的文件压缩为linux.zip。打开Xshell工具,连接一台Linux测试机(我的测试机操作系统是CentOS7.3),在测试机上新建/srv/Worker目录:mkdir/srv/Worker使用rz命令将linux.zip复制到测试机,然后解压linux.zip到测试机的/srv/Worker目录下:unziplinux.zip-d/srv/Worker给我们的应用分配可执行权限,运行:#Assignexecutablepermissionschmod+x/srv/Worker/MyService#Run/srv/Worker/MyService按Ctrl+C关闭应用,等待关闭前必须完成的任务正常完成,然后退出应用。输入ls/srv/Worker命令回车,会看到该目录下多了一个Logs目录,日志文件输出正常。作为Systemd服务运行§添加Systemd服务依赖项为了让我们的Worker监听来自Systemd的启动和停止信号,我们需要添加Microsoft.Extensions.Hosting.SystemdNuGet包:dotnetaddpackageMicrosoft.Extensions.Hosting.Systemd然后,我们需要修改程序。在cs中的CreateHostBuilder方法中,添加UseSystemd方法调用,设置主机(Host)生命周期为Microsoft.Extensions.Hosting.Systemd.SystemdLifetime,使应用程序可以接收启动和停止信号,配置控制台输出被记录系统格式。publicstaticIHostBuilderCreateHostBuilder(string[]args)=>Host.CreateDefaultBuilder(args).UseSystemd()//设置主机生命周期为Microsoft.Extensions.Hosting.Systemd.SystemdLifetime....ConfigureServices((hostContext,services)=>{{AddHostedService();}).UseSerilog();//设置Serilog为日志提供者,重新运行如下命令将程序发布到文件夹:dotnetpublish-cRelease-rlinux-x64-oc:\test\workerpub\linux然后重复前面的步骤,在Xshell中使用rz命令将应用复制到测试机上,并为/srv/Worker/MyService文件赋予可执行权限。§配置文件接下来我们需要创建一个配置文件来告诉systemd有关该服务的信息,以便它知道如何运行它。为此,我们需要创建一个.service文件,我们将在注册和运行该服务的Linux机器上使用该文件。在我们的项目中创建一个名为MyService.service的服务单元配置文件,内容如下:[Unit]Description=Longrunningservice/daemoncreatedfrom.NETworkertemplate[Service]#ThesystemdservicefilemustbeconfiguredwithType=notifytoenablenotifications.Type=notify#willsettheCurrentWorkingDirectory(CWD).WorkerservicewillhaveissueswithoutthissettingWorkingDirectory=/srv/Worker#systemdwillrunthisexecutabletostarttheserviceExecStart=/srv/Worker/MyService#toquerylogsusingjournalctl,setalogicalnamehereSyslogIdentifier=MyService#Useyourusernametokeepthingssimple.#Ifyoupickadifferentuser,makesuredotnetandallpermissionsaresetcorrectlytoruntheapp#Toupdatepermissions,use'chownyourusername-R/srv/Worker'totakeownershipofthefolderandfiles,#Use'chmod+x/srv/Worker/MyService'toallowexecutionoftheexecutablefileUser=yourusername#Thisenvironmentvariableisnecessarywhendotnetisn'tloadedforthespecifieduser.#Tofigureoutthisvalue,run'env|grepDOTNET_ROOT'whendotnethasbeenloadedintoyourshell.Environment=DOTNET_ROOT=/usr/share/dotnet/dotnet#ThisgivestimetoMyServicetoshutdowngracefully.TimeoutStopSec=300[Install]WantedBy=multi-user.target使用时,要把User=yourusername项中的yourusername改成具体linux系统的登录名Systemd期望所有的配置文件都是放在/etc/systemd/system/目录下,我们打开这个目录,使用rz命令将服务配置文件复制到/etc/systemd/system/MyService.service,cd/etc/systemd/system/rz和然后执行以下命令让systemd重新加载配置文件:systemctldaemon-reload§管理服务后,可以运行以下命令查看systemd是否识别我们的服务:systemctlstatusMyService结果如下:这表明我们的新服务registered被禁用,可以通过运行以下命令来启动它:systemctlstartMyService重新运行systemctlstatusMyService命令查看服务状态,如下图:tostopt服务,可以运行以下命令:systemctlstopMyService如果希望服务在开机时自动启动,可以运行以下命令:systemctlenableMyService禁用开机自动启动,可以运行以下命令:systemctldisableMyService来检查服务是否启动自动启动,可以运行以下命令:systemctlis-enabledMyService§Systemd服务日志命令journalctl可以用来查看systemd收集的日志。systemd-journald服务负责systemd的日志收集,它从内核、systemd服务和其他来源检索信息。日志的集中收集方便了日志的检索和查询。日志中的日志记录是结构化和索引化的,因此journalctl可以以各种有用的格式呈现日志信息。我们可以使用journalctl命令来验证应用程序是否成功运行,因为它可以跟踪应用程序的输出:journalctl-uMyService-f按Ctrl-C退出命令。当我们在程序中调用UseSystemd方法时,Extensions.LogLevel会映射到Syslog日志级别:LogLevelSyslog级别systemd名称Trace/Debug7debugInformation6infoWarning4warningError3errCritical2crit所以,我们可以使用journalctl命令优先级标志(priority-flag)-p根据日志级别过滤应用程序的输出信息:journalctl-p4-uMyService-f总结在这篇文章中,我已经详细介绍了如何部署.NETWorker通过实例服务到Linux系统作为SystemdService运行,并讲解了如何使用systemctl命令管理服务,以及如何使用journalctl命令查看Systemd服务日志。当我们将.UseSystemd()方法调用添加到HostBuilder时,编译后的程序既可以作为Linux控制台应用程序运行,也可以作为Systemd服务运行。您可以从GitHub下载本文的源代码。参考:https://swimburger.net/blog/dotnet/how-to-run-a-dotnet-core-console-app-as-a-service-using-systemd-on-linuxhttps://devblogs.microsoft。com/dotnet/net-core-and-systemd/https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publishhttps://www.freedesktop.org/wiki/Software/systemd/https://systemd.io/https://www.linode.com/docs/guides/how-to-use-journalctl/https://github.com/ITTranslate/WorkerServiceAsWindowsService上一篇文章源码https://github.com/ITTranslate/WorkerServiceAsSystemdService本文源码