Supervisor守護DotNet Core控制台程序


Supervisor 相信對Linux系統很熟的都知道這個軟件,基於Python寫的一個守護進程軟件(實現后台運行)。具體的介紹和使用我就不再贅述了。

使用asp.net core 部署在Linux常用的方法 我們可以用Docker、Jexus 、Supervisor等。具體應該使用哪個,因不同的軟件都有各自的優缺點,根據自身應用的場景選擇一個即可。

在使用Supervisor  部署asp.net core的時候通常我們只要在supervisord.d 目錄中添加對應的配置文件如xxx.ini或xxx.conf。(具體目錄位置和配置文件擴展名請根據supervisord.conf來進行配置約束。)

然后在配置文件command 后面寫上dotnet /data/web/webapi.dll ,然后通過 supervisorctl start webapi 即可啟動我們的web程序在后台運行。

當我們在DotNet Core中寫一個后台程序,比如定時任務程序、MQ的消費者程序等。這樣就沒必要寫成Web程序;在windows里我們可以寫一個windows服務程序,直接在后台運行。但是DotNet Core我們只能寫控制台程序了。

普通的控制台程序我們寫好后放到Linux上直接運行沒問題,但是如果使用supervisor 進行部署實現后台進程守護(部署方式同asp.net core一樣),會發現 怎么也啟動不了。

比如這樣一個程序

Linux上直接運行(前台方式),可以完美執行。

使用Supervisord部署添加一個配置文件

使用supervisor運行,會出現錯誤。

出現錯誤不能成功運行,如果網上搜索 "supervisor Exited too quickly (process log may have details)”或按照supervisor日志里的錯誤信息搜索,多數會告訴你目錄是否配置錯誤、目錄是否有對應權限、dotnet 命令是否能正常運行等。

我們看看運行日志

這樣看是有運行,出現【控制台程序已經啟動】多次說明我們的程序被Supervisor 多次重啟了,在配置文件中startretries就是啟動失敗后重啟次數。

我們可以通過tail -f /data/logs/apptest.log 查看日志有沒有文件有沒有繼續持續輸出我們打印的時間或者通過ps -efl |grep dotnet 查看當前程序運行的進程是否存在,后者是最准確的。

不難發現我們本次是有運行 因為有啟動日志,但是很快進程就會自動退出了。

為控制台程序添加宿主

在asp.net core中我們都知道有個WebHost

asp.net core 中的WebHost

在控制台中我們需要添加HostBuilder來作為宿主。

通過Nuget 添加Microsoft.Extensions.Hosting

修改控制台的Main函數

static async Task Main(string[] args)
{
    Console.WriteLine($"控制台程序已經啟動:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}\r\n");

    var hostBuilder = new HostBuilder()
   .ConfigureServices(serviceCollection =>
   {
       //注冊我們的服務接口
       serviceCollection.AddSingleton<IHostedService, MyService>();
   });
    await hostBuilder.RunConsoleAsync();
}

 一般情況Main函數改為異步后變異會報錯,會提示找不到合適的靜態入口;可以設置語言版本為C#7.1及以上來解決。

 

我們需要添加一個服務文類用來繼承我們的宿主IHostedService接口,並重寫服務啟動和結束方法。

class MyService : IHostedService
    {
        /// <summary>
        /// 服務啟動
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StartAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                Console.WriteLine("控制台程序已經開啟");
                //模擬定時需要后台處理的任務
                new Task(() =>
                {
                    while (true)
                    {
                        Console.WriteLine("當前時間是:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        Thread.Sleep(1000);
                    }
                }).Start();

            });
        }
        /// <summary>
        /// 服務停止
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                Console.WriteLine("控制台程序已經停止");
            });

       }
    }

 發布然后使用supervisorctl start apptest 開啟看看

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM