[英]Launching linux process from asp.net core application fail (file not found)
[英]How to create PID file from ASP.NET Core application under Linux
我寫了一個 ASP.NET Core 應用程序(實際上是 .NET 5)並在 Linux 下作為系統服務運行它(遵循這個 Microsoft 指南)。 然后我想用monit application來監控這個應用程序。 此應用程序需要服務來創建 PID 文件,以便它們很容易被發現。 我決定寫一個問答式的問題來幫助其他人更快地實現同樣的目標。
注意:此處描述的解決方案是我的NuGet package的一部分,如果您更喜歡通過 package 方式實現目標,可以在 github上獲得開源。
.NET Core 中有幾種運行后台任務的方法。 IHostedService
是其中之一,它包含StartAsync
方法,該方法在服務注冊后在啟動時調用。 該接口還定義了在正常關閉時調用的StopAsync
。 有關IHostedService
的更多詳細信息,請訪問此 Microsoft 頁面。
知道我們可以創建自己的 IHostedService 來管理我們應用程序的 PID 文件:
public class PidFileHostedService : IHostedService
{
private readonly ILogger<PidFileHostedService> logger;
private readonly IConfiguration configuration;
private readonly IWebHostEnvironment env;
private bool isPidFileCreated = false;
private string pidFile = string.Empty;
public PidFileHostedService(ILogger<PidFileHostedService> logger,
IConfiguration configuration,
IWebHostEnvironment env)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
this.env = env ?? throw new ArgumentNullException(nameof(env));
}
public async Task StartAsync(CancellationToken cancellationToken)
{
try
{
if (env.IsDevelopment())
return;
pidFile = configuration.GetValue<string>("PidFile");
if (string.IsNullOrWhiteSpace(pidFile))
return;
await WritePidFile();
isPidFileCreated = true;
}
catch (Exception ex)
{
logger.LogError(ex, $"Unexpected error when starting {nameof(PidFileHostedService)}", null);
}
}
private async Task WritePidFile()
{
var processId = Environment.ProcessId.ToString();
await File.WriteAllTextAsync(pidFile, processId);
}
public Task StopAsync(CancellationToken cancellationToken)
{
try
{
if (isPidFileCreated)
File.Delete(pidFile);
}
catch (Exception ex)
{
logger.LogError(ex, "Unexpected error when deleting PID file", null);
}
return Task.CompletedTask;
}
}
此服務假定應用程序的 appsettings.json 文件中存在PidFile
屬性。 不要忘記在 Startup.cs 中注冊服務:
services.AddHostedService<PidFileHostedService>();
正如我在問題中所寫,我使用了關於如何讓我的應用程序作為系統服務運行的 Microsoft 指南。 現在,在更改之后,該服務必須對將在其中創建 PID 文件的目錄具有必要的權限。 可以將具有必要權限的此目錄的創建委托給 systemd。 將此行添加到[Service]
部分下的服務文件中就足夠了:
RuntimeDirectory=helloapp
由於這一行,systemd 將在每個服務啟動時在/var/run
中創建helloapp
子目錄,並具有必要的權限。 將以下行添加到同一部分也是一個好主意,它將告訴 systemd 仔細檢查應用程序停止后是否刪除了 PID 文件:
PIDFile=/var/run/helloapp/helloapp.pid
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.