欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用C#编写Linux守护进程实例代码

程序员文章站 2023-12-19 21:16:16
前言 linux守护进程是linux的后台服务进程,相当于windows服务,对于为linux开发服务程序的朋友来说,linux守护进程相关技术是必不可少的,因为这个技术...

前言

linux守护进程是linux的后台服务进程,相当于windows服务,对于为linux开发服务程序的朋友来说,linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展到多进程,父子进程文件描述符共享,父子进程通讯、控制等方面,是实现linux大型服务的基础技术之一。

如果要在red hat enterprise linux上将.net core进程作为后台进程运行,则可以创建自定义systemd单元。今天我将为.net core编写两个自定义系统单元的例子。一个是运行.net core控制台应用程序的一种类型,另一个是运行asp.net core web应用程序的简单类型。

控制台应用程序

建立一个应用程序

您可以用dotnet run在systemd中使用指定项目目录作为工作目录。但是,我们来构建一个二进制文件并将其用于systemd。用dotnet new 命令创建您的项目后编辑program.cs如下。

using system;
using system.io;
namespace consoleapplication
{
 public class program
 {
  public static void main(string[] args)
  {
   var path = path.gettempfilename();
   file.writealltext(path, "hello temp file!");
   console.writeline($"wrote temp file: {path}");
  }
 }
}

然后用dotnet publish命令发布项目。你会看到bin/<configuration>/<framework>目录下的二进制文件。

$ dotnet publish -c release
publishing consoleapp for .netcoreapp,version=v1.1
project consoleapp (.netcoreapp,version=v1.1) was previously compiled. skipping compilation.
publish: published to /home/tatanaka/documents/git/tanaka-takayoshi/systemdexample/1.1/consoleapp/bin/release/netcoreapp1.1/publish
published 1/1 projects successfully

创建一个自定义的systemd

首先,创建一个运行守护进程和工作目录的用户。

$ sudo useradd -s /sbin/nologin dotnetuser
$ sudo mkdir /var/systemdexample
$ sudo cp /home/tatanaka/documents/git/tanaka-takayoshi/systemdexample/1.1/consoleapp/bin/release/netcoreapp1.1/publish/* /var/systemdexample
$ sudo chown -r dotnetuser:dotnetuser /var/systemdexample

然后在/etc/systemd/system/目录下创建一个自定义的systemd单元文件。文件名应该是<unit-name>.<unit-type>。我创建的目录和文件名为:/etc/systemd/system/netcore-console-example.service。

[unit]
description=example for .net core consoleapp with systemd
defaultdependencies=no
 
[service]
type=oneshot
remainafterexit=no
execstart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet consoleapp.dll
workingdirectory=/var/systemdexample
user=dotnetuser
group=dotnetuser
 
 
[install]

您应该在execstart中指定dotnet的完整路径。以上是红帽提供的.net core 1.1的情况。然后你可以用systemctl命令执行守护进程。您可以使用systemctl status命令或journalctl命令查看控制台输出。

$ sudo systemctl start netcore-console-example.service
$ sudo systemctl status netcore-console-example.service
● netcore-console-example.service - example for .net core consoleapp with systemd
 loaded: loaded (/etc/systemd/system/netcore-console-example.service; enabled; vendor preset: disabled)
 active: inactive (dead) since fri 2017-02-24 00:29:16 jst; 13s ago
 process: 18075 execstart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet consoleapp.dll (code=exited, status=0/success)
 main pid: 18075 (code=exited, status=0/success)
 
feb 24 00:29:16 localhost.localdomain systemd[1]: starting example for .net core consoleapp with systemd...
feb 24 00:29:16 localhost.localdomain dotnet[18075]: wrote temp file: /tmp/tmph1ok6h.tmp
feb 24 00:29:16 localhost.localdomain systemd[1]: started example for .net core consoleapp with systemd.
 
$ journalctl -u netcore-console-example.service -e
feb 24 00:29:16 localhost.localdomain systemd[1]: starting example for .net core consoleapp with systemd...
feb 24 00:29:16 localhost.localdomain dotnet[18075]: wrote temp file: /tmp/tmph1ok6h.tmp
feb 24 00:29:16 localhost.localdomain systemd[1]: started example for .net core consoleapp with systemd.
$ sudo cat /tmp/tmph1ok6h.tmp
hello temp file!

使用privatetemp

在上述系统单元中,程序在临时文件夹下写入一个文件。你有时想写一个来自其他用户的临时文件是安全的。您可以在[service]section中的指定使用privatetemp。

[service]
type=oneshot
remainafterexit=no
execstart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet consoleapp.dll
workingdirectory=/var/systemdexample
user=dotnetuser
group=dotnetuser
privatetemp=true

重新加载单元文件后,程序可以像前一样访问/tmp目录,但这不是实际的/tmp目录。

$ sudo systemctl daemon-reload 
$ sudo systemctl start netcore-console-example.service
$ sudo systemctl status netcore-console-example.service
● netcore-console-example.service - example for .net core consoleapp with systemd
 loaded: loaded (/etc/systemd/system/netcore-console-example.service; enabled; vendor preset: disabled)
 active: inactive (dead) since fri 2017-02-24 00:35:46 jst; 12s ago
 process: 18415 execstart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet consoleapp.dll (code=exited, status=0/success)
 main pid: 18415 (code=exited, status=0/success)
 
feb 24 00:35:46 localhost.localdomain systemd[1]: starting example for .net core consoleapp with systemd...
feb 24 00:35:46 localhost.localdomain dotnet[18415]: wrote temp file: /tmp/tmpjlwagc.tmp
feb 24 00:35:46 localhost.localdomain systemd[1]: started example for .net core consoleapp with systemd.
$ ls /tmp/tmpjlwagc.tmp
ls: cannot access /tmp/tmpjlwagc.tmp: no such file or directory

web应用程序

建立一个应用程序

现在我们来构建一个asp.net core web应用程序。今天我使用默认的模板项目。

$ dotnet new -t web
created new c# project in /home/tatanaka/documents/git/tanaka-takayoshi/systemdexample/1.1/webapp.
$ dotnet restore 
** snipped**
log : restore completed in 9721ms.
$ dotnet publish -c release
publishing webapp for .netcoreapp,version=v1.1
** snipped **
publish: published to /home/tatanaka/documents/git/tanaka-takayoshi/systemdexample/1.1/webapp/bin/release/netcoreapp1.1/publish
published 1/1 projects successfully

现在可以用dotnet命令运行。

$ dotnet bin/release/netcoreapp1.1/publish/webapp.dll 
info: microsoft.extensions.dependencyinjection.dataprotectionservices[0]
  user profile is available. using '/home/tatanaka/.aspnet/dataprotection-keys' as key repository; keys will not be encrypted at rest.
hosting environment: production
content root path: /home/tatanaka/documents/git/tanaka-takayoshi/systemdexample/1.1/webapp
now listening on: http://localhost:5000
application started. press ctrl+c to shut down.

创建一个自定义的systemd

为这个web应用程序也指定dotnetuser名称。

$ sudo mkdir /var/systemdexample
$ sudo cp -r bin/release/netcoreapp1.1/publish/* /var/systemdwebexample
$ sudo chown -r dotnetuser:dotnetuser /var/systemdwebexample

然后创建一个自定义的systemd单元文件/etc/systemd/system/netcore-web-example.service。

[unit]
description=example for .net core webapp with systemd
defaultdependencies=no
wants=network.target # network is required
after=network.target
 
[service]
execstart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet webapp.dll
workingdirectory=/var/systemdwebexample
restart=always
restartsec=10 # restart service after 10 seconds if dotnet service crashes
syslogidentifier=dotnet-example
user=dotnetuser
group=dotnetuser
privatetmp=true
environment=aspnetcore_environment=production # specify environment variable for environment
environment=aspnetcore_urls=http://*:8080 # specify environement variable for listening port
 
[install]
wantedby = multi-user.target

最后,您可以将asp.net core应用程序作为linux守护程序运行。请注意,此应用程序侦听端口8080代替了asp.net core 默认的 5000,因为我在aspnetcore_urls单元文件中指定了环境变量  。

$ systemctl start netcore-web-example.service
[tatanaka@localhost webapp]$ systemc^c
[tatanaka@localhost webapp]$ sudo systemctl status netcore-web-example.service
[sudo] password for tatanaka: 
● netcore-web-example.service - example for .net core webapp with systemd
 loaded: loaded (/etc/systemd/system/netcore-web-example.service; disabled; vendor preset: disabled)
 active: active (running) since sat 2017-02-25 01:02:12 jst; 11s ago
 main pid: 7041 (dotnet)
 cgroup: /system.slice/netcore-web-example.service
   └─7041 /opt/rh/rh-dotnetcore11/root/usr/bin/dotnet webapp.dll
 
feb 25 01:02:12 localhost.localdomain systemd[1]: started example for .net core webapp with systemd.
feb 25 01:02:12 localhost.localdomain systemd[1]: starting example for .net core webapp with systemd...
feb 25 01:02:12 localhost.localdomain dotnet-example[7041]: info: microsoft.extensions.dependencyinjection.dataprotectionservices[0]
feb 25 01:02:12 localhost.localdomain dotnet-example[7041]: user profile is available. using '/home/dotnetuser/.aspnet/dataprotection-keys' as key repository; keys will not be encrypted at rest.
feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: hosting environment: production
feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: content root path: /var/systemdwebexample
feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: now listening on: http://*:8080
feb 25 01:02:13 localhost.localdomain dotnet-example[7041]: application started. press ctrl+c to shut down.
 
$ journalctl -u netcore-web-example -xf
-- logs begin at mon 2017-02-20 11:58:31 jst. --
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: microsoft.aspnetcore.staticfiles.staticfilemiddleware[2]
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: sending file. request path: '/images/banner4.svg'. physical path: '/var/systemdwebexample/wwwroot/images/banner4.svg'
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: microsoft.aspnetcore.hosting.internal.webhost[2]
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: request finished in 0.1973ms 200 image/svg+xml
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: microsoft.aspnetcore.hosting.internal.webhost[1]
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: request starting http/1.1 get http://localhost:8080/favicon.ico
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: microsoft.aspnetcore.staticfiles.staticfilemiddleware[2]
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: sending file. request path: '/favicon.ico'. physical path: '/var/systemdwebexample/wwwroot/favicon.ico'
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: info: microsoft.aspnetcore.hosting.internal.webhost[2]
feb 25 01:02:36 localhost.localdomain dotnet-example[7041]: request finished in 0.5824ms 200 image/x-icon

然而这对于asp.net core的生产使用来说是不够的。你可能需要设置一个反向代理服务器,比如jexus,nginx,防火墙等等。

writing a linux daemon in c#

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

上一篇:

下一篇: