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 开启看看
来源: https://www.cnblogs.com/rui1236/p/10774551.html