zoukankan      html  css  js  c++  java
  • 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")}
    ");
    
        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 开启看看

  • 相关阅读:
    python 发送邮件
    java 获取两个时间之前所有的日期
    java 子线程定时去更改主线程的变量
    post 两种方式 application/x-www-form-urlencoded和multipart/form-data
    aws 社交媒体技术大会 部分总结
    java操作Mongodb数据库
    实体类注解 @entity
    spring security 部分注解讲解
    @Column
    阿里云搭建服务器
  • 原文地址:https://www.cnblogs.com/rui1236/p/10774551.html
Copyright © 2011-2022 走看看