虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > C#编程 > 利用C#编写Linux守护进程实例代码

利用C#编写Linux守护进程实例代码
类别:C#编程   作者:码皇   来源:互联网   点击:

如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件,下面这篇文章主要给大家介绍了关于利用C#编写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 ReleasePublishing ConsoleApp for .NETCoreApp,Version=v1.1Project 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/publishPublished 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 systemdDefaultDependencies=no [Service]Type=oneshotRemainAfterExit=noExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dllWorkingDirectory=/var/SystemdExampleUser=dotnetuserGroup=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.tmpFeb 24 00:29:16 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd. $ journalctl -u netcore-console-example.service -eFeb 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.tmpFeb 24 00:29:16 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd.$ sudo cat /tmp/tmph1ok6H.tmpHello Temp File!

使用PrivateTemp

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

    [Service]Type=oneshotRemainAfterExit=noExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet ConsoleApp.dllWorkingDirectory=/var/SystemdExampleUser=dotnetuserGroup=dotnetuserPrivateTemp=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.tmpFeb 24 00:35:46 localhost.localdomain systemd[1]: Started Example for .NET Core ConsoleApp with systemd.$ ls /tmp/tmpJLWAGC.tmpls: cannot access /tmp/tmpJLWAGC.tmp: No such file or directory

Web应用程序

建立一个应用程序

现在我们来构建一个ASP.NET Core Web应用程序。今天我使用默认的模板项目。

    $ dotnet new -t webCreated 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 ReleasePublishing WebApp for .NETCoreApp,Version=v1.1** snipped **publish: Published to /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/WebApp/bin/Release/netcoreapp1.1/publishPublished 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: ProductionContent root path: /home/tatanaka/Documents/git/tanaka-takayoshi/SystemdExample/1.1/WebAppNow listening on: http://localhost:5000Application 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 systemdDefaultDependencies=noWants=network.target # network is requiredAfter=network.target [Service]ExecStart=/opt/rh/rh-dotnetcore11/root/usr/bin/dotnet WebApp.dllWorkingDirectory=/var/SystemdWebExampleRestart=alwaysRestartSec=10 # Restart service after 10 seconds if dotnet service crashesSyslogIdentifier=dotnet-exampleUser=dotnetuserGroup=dotnetuserPrivateTmp=trueEnvironment=ASPNETCORE_ENVIRONMENT=Production # specify environment variable for environmentEnvironment=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: ProductionFeb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Content root path: /var/SystemdWebExampleFeb 25 01:02:13 localhost.localdomain dotnet-example[7041]: Now listening on: http://*:8080Feb 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+xmlFeb 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.icoFeb 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#

总结

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

您可能感兴趣的文章:

  • linux shell实现守护进程脚本
  • C语言编写Linux守护进程实例
  • 使用Python编写Linux系统守护进程实例
  • Java实现Linux下双守护进程
  • linux下的守护进程
  • Linux守护进程的启动方法
  • linux 创建守护进程的相关知识
  • linux 守护进程详解及建立守护进程
  • linux下如何创建守护进程的步骤
相关热词搜索: linux 守护进程 linux c 守护进程 linux守