利用C#編寫Linux守護(hù)進(jìn)程實(shí)例代碼
前言
Linux守護(hù)進(jìn)程是Linux的后臺(tái)服務(wù)進(jìn)程,相當(dāng)于Windows服務(wù),對(duì)于為L(zhǎng)inux開(kāi)發(fā)服務(wù)程序的朋友來(lái)說(shuō),Linux守護(hù)進(jìn)程相關(guān)技術(shù)是必不可少的,因?yàn)檫@個(gè)技術(shù)不僅僅是為了開(kāi)發(fā)守護(hù)進(jìn)程,還可以拓展到多進(jìn)程,父子進(jìn)程文件描述符共享,父子進(jìn)程通訊、控制等方面,是實(shí)現(xiàn)Linux大型服務(wù)的基礎(chǔ)技術(shù)之一。
如果要在Red Hat Enterprise Linux上將.NET Core進(jìn)程作為后臺(tái)進(jìn)程運(yùn)行,則可以創(chuàng)建自定義systemd單元。今天我將為.NET Core編寫兩個(gè)自定義系統(tǒng)單元的例子。一個(gè)是運(yùn)行.NET Core控制臺(tái)應(yīng)用程序的一種類型,另一個(gè)是運(yùn)行ASP.NET Core Web應(yīng)用程序的簡(jiǎn)單類型。
控制臺(tái)應(yīng)用程序
建立一個(gè)應(yīng)用程序
您可以用dotnet run在systemd中使用指定項(xiàng)目目錄作為工作目錄。但是,我們來(lái)構(gòu)建一個(gè)二進(jìn)制文件并將其用于systemd。用dotnet new 命令創(chuàng)建您的項(xiàng)目后編輯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命令發(fā)布項(xiàng)目。你會(huì)看到bin/<Configuration>/<Framework>目錄下的二進(jìn)制文件。
$ 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
創(chuàng)建一個(gè)自定義的systemd
首先,創(chuàng)建一個(gè)運(yùn)行守護(hù)進(jìn)程和工作目錄的用戶。
$ 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/目錄下創(chuàng)建一個(gè)自定義的systemd單元文件。文件名應(yīng)該是<unit-name>.<unit-type>。我創(chuàng)建的目錄和文件名為:/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]
您應(yīng)該在ExecStart中指定dotnet的完整路徑。以上是紅帽提供的.NET Core 1.1的情況。然后你可以用systemctl命令執(zhí)行守護(hù)進(jìn)程。您可以使用systemctl status命令或journalctl命令查看控制臺(tái)輸出。
$ 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
在上述系統(tǒng)單元中,程序在臨時(shí)文件夾下寫入一個(gè)文件。你有時(shí)想寫一個(gè)來(lái)自其他用戶的臨時(shí)文件是安全的。您可以在[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
重新加載單元文件后,程序可以像前一樣訪問(wèn)/tmp目錄,但這不是實(shí)際的/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應(yīng)用程序
建立一個(gè)應(yīng)用程序
現(xiàn)在我們來(lái)構(gòu)建一個(gè)ASP.NET Core Web應(yīng)用程序。今天我使用默認(rèn)的模板項(xiàng)目。
$ 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
現(xiàn)在可以用dotnet命令運(yùn)行。
$ 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.
創(chuàng)建一個(gè)自定義的systemd
為這個(gè)Web應(yīng)用程序也指定dotnetuser名稱。
$ sudo mkdir /var/SystemdExample $ sudo cp -R bin/Release/netcoreapp1.1/publish/* /var/SystemdWebExample $ sudo chown -R dotnetuser:dotnetuser /var/SystemdWebExample
然后創(chuàng)建一個(gè)自定義的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應(yīng)用程序作為L(zhǎng)inux守護(hù)程序運(yùn)行。請(qǐng)注意,此應(yīng)用程序偵聽(tīng)端口8080代替了ASP.NET Core 默認(rèn)的 5000,因?yàn)槲以贏SPNETCORE_URLS單元文件中指定了環(huán)境變量 。
$ 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
然而這對(duì)于ASP.NET Core的生產(chǎn)使用來(lái)說(shuō)是不夠的。你可能需要設(shè)置一個(gè)反向代理服務(wù)器,比如Jexus,nginx,防火墻等等。
Writing a Linux daemon in C#
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)我們的支持。
欄 目:C#教程
下一篇:詳解C# 代碼占用的空間
本文標(biāo)題:利用C#編寫Linux守護(hù)進(jìn)程實(shí)例代碼
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5256.html
您可能感興趣的文章
- 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
- 01-10C#圖片處理3種高級(jí)應(yīng)用
- 01-10輕松學(xué)習(xí)C#的正則表達(dá)式
- 01-10分享一個(gè)C#編寫簡(jiǎn)單的聊天程序(詳細(xì)介紹)
- 01-10C#異步下載文件
- 01-10C# Console利用mspaint打開(kāi)圖像并保存的方法
- 01-10C#利用delegate實(shí)現(xiàn)Javascript的each方法
- 01-10使用C#編寫簡(jiǎn)單的圖形化的可發(fā)送附件的郵件客戶端程序
- 01-10Windows中使用C#為文件夾和文件編寫密碼鎖的示例分享
- 01-10C#使用Process類調(diào)用外部exe程序


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子