自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Dotnet創(chuàng)建Linux下的Service應(yīng)用

系統(tǒng) Linux
說到服務(wù)端應(yīng)用,最常見的就是API服務(wù)。除此之外,還有一類應(yīng)用,比方一個Socket的服務(wù)器。這類型的應(yīng)用,本身沒有Web層,當(dāng)然也不屬于API服務(wù)。

[[403140]]

本文轉(zhuǎn)載自微信公眾號「老王Plus」,作者老王Plus的老王 。轉(zhuǎn)載本文請聯(lián)系老王Plus公眾號。

前言

說到服務(wù)端應(yīng)用,最常見的就是API服務(wù)。

除此之外,還有一類應(yīng)用,比方一個Socket的服務(wù)器。這類型的應(yīng)用,本身沒有Web層,當(dāng)然也不屬于API服務(wù)。

通常大家會怎么做?

不講究的做法,就是做一個Console應(yīng)用,加載到后臺一直跑著。

其實,還有另外一種做法,就是把應(yīng)用加載到Services里,使應(yīng)用以一個Service來做響應(yīng)。這樣可以依托操作系統(tǒng)的Services管理器來進(jìn)行統(tǒng)一管理,自動運行和故障處理。

Dotnet做Window Service的內(nèi)容,網(wǎng)上有很多。我今天寫一個在Linux下做Service的方法。

創(chuàng)建Linux下的Service應(yīng)用

創(chuàng)建一個LInux下的Service應(yīng)用其實很簡單,就分這么幾步:

1. 用 Worker 模板創(chuàng)建工程

如果習(xí)慣用VS上創(chuàng)建,就找一下Worker Service模板。

我是習(xí)慣從命令行創(chuàng)建,就一條命令:

  1. % dotnet new worker -o projectname 

Dotnet會自動造成工程,并自動引用Microsoft.Extensions.Hosting包,因為這本身是一個Self-Hosting應(yīng)用。

2. 加入Linux Service擴(kuò)展包

其實這就是一個包:Microsoft.Extensions.Hosting.Systemd。這個包為應(yīng)用提供了在Linux下使用Systemd守護(hù)進(jìn)程的基礎(chǔ)配置。

還是命令行:

  1. % dotnet add package Microsoft.Extensions.Hosting.Systemd 

3. 修改Program.cs

其實就是一行代碼,把第二步引入的包加入應(yīng)用。修改Program.cs

  1. public static IHostBuilder CreateHostBuilder(string[] args) => 
  2.     Host.CreateDefaultBuilder(args) 
  3.         .UseSystemd()  // 加入的就是這一行。 
  4.         .ConfigureServices((hostContext, services) => 
  5.         { 
  6.             services.AddHostedService<Worker>(); 
  7.         }); 

到這兒,套路性的工作已經(jīng)完成。簡單吧?

我們來看一下現(xiàn)在的工程:

  1. ├── Program.cs 
  2. ├── Properties 
  3. │   └── launchSettings.json 
  4. ├── Worker.cs 
  5. ├── appsettings.Development.json 
  6. ├── appsettings.json 
  7. └── workerdemo.csproj 

大家會注意到,里面多了一個Worker.cs的類文件。

看一下這個文件:

  1. public class Worker : BackgroundService 
  2.     private readonly ILogger<Worker> _logger; 
  3.  
  4.     public Worker(ILogger<Worker> logger) 
  5.     { 
  6.         _logger = logger; 
  7.     } 
  8.  
  9.     protected override async Task ExecuteAsync(CancellationToken stoppingToken) 
  10.     { 
  11.         while (!stoppingToken.IsCancellationRequested) 
  12.         { 
  13.             _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); 
  14.             await Task.Delay(1000, stoppingToken); 
  15.         } 
  16.     } 

這其實就是加載到Systemd里的服務(wù)的模板。我們需要的服務(wù)代碼,需要加到ExecuteAsync(CancellationToken stoppingToken)方法中。

我簡單做個例子,在里面加入UDP服務(wù),看代碼:

  1. public class Worker : BackgroundService 
  2.     private readonly ILogger<Worker> _logger; 
  3.     private readonly IConfiguration _configuration; 
  4.  
  5.     public Worker(ILogger<Worker> logger, IConfiguration configuration) 
  6.     { 
  7.         _logger = logger; 
  8.         _configuration = configuration; 
  9.     } 
  10.  
  11.     protected override async Task ExecuteAsync(CancellationToken stoppingToken) 
  12.     { 
  13.         _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); 
  14.  
  15.         UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000)); 
  16.  
  17.         while (!stoppingToken.IsCancellationRequested) 
  18.         { 
  19.             UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync(); 
  20.  
  21.             string message = Encoding.UTF8.GetString(udpReceiveResult.Buffer); 
  22.             Console.WriteLine($"{udpReceiveResult.RemoteEndPoint.ToString()} - {message}"); 
  23.  
  24.             await udpClient.SendAsync(Encoding.Default.GetBytes("Got"), 3, udpReceiveResult.RemoteEndPoint); 
  25.         } 
  26.     } 

這個代碼中,有兩件事需要注意:

  1. 在前邊Program.cs中加入UseSystemd()時,已經(jīng)注入了IConfiguration。因此,可以在這個方法中直接引入并使用。換句話說,就是可以直接讀取例如appsetting.json的內(nèi)容;
  2. 是上邊提到的,真正的服務(wù)響應(yīng)在ExecuteAsync(CancellationToken stoppingToken)中。這兒沒什么特別的,就是正常的寫法。

上面這個,是服務(wù)端的程序,是響應(yīng)。

下面我簡單做個客戶端的請求,供測試用。就不解釋了,只列出步驟:

創(chuàng)建一個工程

  1. % dotnet new console -o democlient 

修改Program.cs

  1. static async Task Main(string[] args) 
  2.     UdpClient udpClient = new UdpClient(); 
  3.  
  4.     for (int i = 0; i < 10000; i++) 
  5.     { 
  6.         byte[] buffer = new byte[8 * 1024]; 
  7.  
  8.         await Task.Run(() => 
  9.         { 
  10.             udpClient.SendAsync(buffer, buffer.Length, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8000)); 
  11.         }); 
  12.  
  13.     } 
  14.     while (true
  15.     { 
  16.         UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync(); 
  17.  
  18.         string message = Encoding.UTF8.GetString(udpReceiveResult.Buffer); 
  19.         Console.WriteLine($"{udpReceiveResult.RemoteEndPoint.ToString()} - {message}"); 
  20.     } 
  21.     Console.ReadKey(); 

運行一下,看看效果。

到這里,Service應(yīng)用開發(fā)的工作已經(jīng)完成。

下面是部署。

部署Service應(yīng)用

Linux下面部署一個Service應(yīng)用,只有兩個步驟:

1. 創(chuàng)建Service定義

Linux下的每個Service,都會有個定義文件。這個文件存在于/etc/systemd/system目錄下。

下面我給出一個簡單的Service模板:

  1. [Unit] 
  2. Description=DemoProject 
  3.  
  4. [Service] 
  5. Type=notify 
  6. ExecStart=dotnet /yourfolder/yourproject.dll 
  7.  
  8. [Install] 
  9. WantedBy=multi-user.target 

把這個內(nèi)容保存為一個文件,例如叫demo.service。然后把這個文件復(fù)制到/etc/systemd/system下,并改為可執(zhí)行。

簡單說一下這個文件的一些項:

  • Description,是服務(wù)的名字。不重要,啟動時,你用到的是文件名demo.service;
  • Type,服務(wù)類型,使用Dotnet加載時,只能是這種類型。如果把程序編譯為自包含程序,這個類型可以是simple;
  • ExecStart,啟動程序的命令,是全路徑的,要確保能找得到這個程序。上面例子中,dotnet /yourfolder/yourproject.dll,是因為dotnet命令是有PATH變量支持的。

這個文件的配置項有很多,包括定義是否需要自動重啟、重啟間隔等。如果需要,可以去這里查詢。

2. 啟動Service

有兩種方法。

第一種是刷新Service守護(hù)

  1. % systemctl daemon-reload 

刷新守護(hù)時,守護(hù)進(jìn)程會去/etc/systemd/system目錄下,尋找新加入的Service文件,并啟動。

第二種是單獨啟動,有一系列命令:

啟動

  1. % systemctl start demo.service 

停止

  1. % systemctl stop demo.service 

重啟

  1. % systemctl restart demo.service 

查詢狀態(tài)

  1. % systemctl status demo.service 

嗯。這就是服務(wù)加載和停止了。

注意,這種方式加載的Service,是完全系統(tǒng)的服務(wù),會沒有任何輸出。

如果需要調(diào)試,一種方式是加文件日志,另一種方式是用另一個命令啟動:

  1. % journalctl -u dnsserver.service 

當(dāng)然,這種方式只用于調(diào)試。正式運行時,還應(yīng)該是上面的方式。

 

責(zé)任編輯:武曉燕 來源: 老王Plus
相關(guān)推薦

2011-05-06 15:48:35

Service BroSQL Server

2020-09-16 23:04:32

Linux創(chuàng)建用戶主adduser

2021-10-10 13:37:36

DialectLinux開源翻譯

2018-01-04 16:08:13

Linux桌面啟動器.desktop文件

2009-08-14 15:02:24

Service模板C#創(chuàng)建

2009-07-22 10:18:20

緩存服務(wù)器

2010-08-27 09:14:32

DHCPdhcpd

2009-08-11 13:27:22

C#創(chuàng)建Web Ser

2009-11-18 09:25:02

linux應(yīng)用程序

2011-05-06 15:37:10

Service BroSQL Server

2009-09-18 13:17:05

2009-04-07 15:45:54

2015-09-01 13:44:57

LinuxRAID 5

2009-12-08 17:16:37

WCF Web Ser

2009-04-13 11:31:55

IBMdWWebService

2021-03-03 08:13:57

模式垃圾回收

2023-03-05 16:36:14

Linux鏈接目標(biāo)文件

2021-12-29 07:44:50

Dotnet 代碼系統(tǒng)

2021-06-29 10:50:40

Linux.NET命令

2011-07-29 10:02:59

Master DataAPIModel
點贊
收藏

51CTO技術(shù)棧公眾號