簡體   English   中英

如何從 ASP.NET 創建 PID 文件 Linux 下的核心應用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM