首页 > 其他分享 >.NET之Kill -15 优雅退出

.NET之Kill -15 优雅退出

时间:2024-04-21 15:45:36浏览次数:25  
标签:args 15 await DateTime WriteLineAsync Kill Console NET Out

背景:运维人员在每次进行代码升级版本的时候,会执行kill 命令关闭进程,再上传代码包。这时候会出现以下问题:

1. 已接收的HTTP请求业务没有处理完成就立即停止进程

如果让程序自动处理完业务后关闭进程会出现以下问题:

1. 拒绝接收新的HTTP请求消息

以下截图是本机代码测试:

 

 

using D.TestKill15;
using D.TestKill15.NLogsUtil;

var builder = WebApplication.CreateBuilder(args);

// NLog 日志
builder.Services.AddNLogUtil();
builder.Services.AddControllers();
//builder.Services.AddHealthChecks();微软的探针,查看服务是否存活
 
builder.WebHost.UseKestrel(o =>
{
    o.ListenAnyIP(5000);
});
var app = builder.Build();
var nlog = app.Services.GetService<INLogService>();

if (args.Length > 0)
{
    await Console.Out.WriteLineAsync($"开始输出args参数,共{args.Length}个");
    nlog.Info($"开始输出args参数,共{args.Length}个");
    foreach (var arg in args)
    {
        await Console.Out.WriteLineAsync(arg);
        nlog.Info(arg);
    }
}
else
{
    await Console.Out.WriteLineAsync($"args入参长度为{args.Length}");
    nlog.Info($"args入参长度为{args.Length}");
}

int requestCount = 0;
bool isExit = false;
app.Use(async (httpContext, next) =>
{
    await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-收到HTTP请求-{requestCount}");
    if (isExit)
    {
        await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-已收到退出程序指令,程序正在退出,拒绝接受新消息");
        httpContext.Abort();
    }
    else
    {
        Interlocked.Increment(ref requestCount);
        try
        {
            await next();
        }
        finally
        {
            Interlocked.Decrement(ref requestCount);
        }
    }
});

// 收到关闭请求
app.Lifetime.ApplicationStopping.Register(async () =>
{
    await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-ApplicationStopping start");
    isExit = true;
    SpinWait.SpinUntil(() => requestCount == 0);

    //Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-等待{20000/1000}s后再关闭");
    //Thread.Sleep(20000); 另外一种方案,延迟多少ms后,自动关闭
    //Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-等待完成,执行关闭");
});

// 执行关闭
app.Lifetime.ApplicationStopped.Register(async () =>
{
    await Console.Out.WriteLineAsync($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-ApplicationStopped start");
});

app.MapControllers();
//app.MapHealthChecks("/healthz"); 
app.Run();

  

 

using D.TestKill15.NLogsUtil;
using Microsoft.AspNetCore.Mvc;

namespace D.TestKill15
{
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        INLogService _nLogService;
        public TestController(INLogService nLogService)
        {
            _nLogService = nLogService;
        }

        [HttpGet("get")]
        public async Task<string> Get(int? delayTime)
        {
            var t = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-收到消息";
            _nLogService.Info(t);
            await Console.Out.WriteLineAsync(t);

            if (delayTime != null)
            {
                var s = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-开始执行函数需要耗费{delayTime}ms";
                _nLogService.Info(s);
                await Console.Out.WriteLineAsync(s);

                await Task.Delay(delayTime.Value);
                var e = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}-函数执行{delayTime}ms完毕";
                _nLogService.Info(e);
                await Console.Out.WriteLineAsync(e);
            }

            var r = $"返回消息:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}";
            await Console.Out.WriteLineAsync(r);
            return r;
        }
    }
}

  

 

标签:args,15,await,DateTime,WriteLineAsync,Kill,Console,NET,Out
From: https://www.cnblogs.com/ingstyle/p/18149008

相关文章

  • VS2015编译并配置boost 64位
    1、下载boost1.72.0,自Boost1.73后需要匹配C++14版本的编译平台了,对于VS2015下载1.73.0之前版本的boost库包均可BoostVersionHistory 2、解压后编译打开下图cmd进入解压目录中运行bootstrap.bat(进入到目录可以输入cd/dd:或者d:),会生成b2.exe输入命令:b2.exe-j4--build......
  • BenchmarkDotNet
    目录官方开源地址和文档HowitworksChoosingRunStrategy简单使用示例BenchmarkDotNet打印列的含义Benchmark输出列Benchmark特性相关参考版权特别声明官方开源地址和文档GitHub:GitHub-dotnet/BenchmarkDotNet:Powerful.NETlibraryforbenchmarking文档首页:Overview|......
  • .Net与AI的强强联合:AntSK知识库项目中Rerank模型的技术突破与实战应用
        随着人工智能技术的飞速发展,.Net技术与AI的结合已经成为了一个新的技术热点。今天,我要和大家分享一个令人兴奋的开源项目——AntSK,这是一个基于.net平台构建的开源离线AI知识库项目。在这个项目中,我们最近加入了一项强大的Rerank(重排)模型,进一步增强了我们的AI知识库的......
  • kubernetes CNI(Container Network Inferface)
    为什么需要CNI在kubernetes中,pod的网络是使用networknamespace隔离的,但是我们有时又需要互相访问网络,这就需要一个网络插件来实现pod之间的网络通信。CNI就是为了解决这个问题而诞生的。CNI是containernetworkinterface的缩写,它是一个规范,定义了容器运行时如何配......
  • ASP.NET MVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(1)
    ASP.NETMVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(1) 本系列的的角色权限管理主要采用Dotnet MVC4工程内置的权限管理模块Simplemembership实现,主要有关文件是InitializeSimpleMembershipAttribute.cs和AccountModels.cs下面是对这两个文件的了解和改造 WebSe......
  • 如何在ASP.NET MVC中的角色中设置权限?
    如何在ASP.NETMVC中的角色中设置权限? 在ASP.NETMVC中,可以通过使用角色和权限来实现访问控制。下面是在ASP.NETMVC中设置角色权限的步骤:创建角色:首先,需要创建角色来表示不同的用户组。可以使用ASP.NET提供的RoleManager类来创建和管理角色。可以在IdentityConfig.cs文......
  • ASP.NET MVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6)
    ASP.NETMVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6) 快过年了,公司事情忙,好几天没有继续写博客,今天开始写账户模块系统登录,账户管理以及登录日志,首先新建登录日志数据表: ViewCode然后更改模型:AccountModels.cs ViewCode创建登录日志模型:M_UsersLoginLogs.cs View......
  • 35-windows通过cmd查看端口占用,并停止该端口,杀死进程kill等命令
     1)cmd命令提示符窗口后,输入“netstat-ano”并按下回车执行,之后就会显示电脑上运行的所有端口号netstat-ano 2) 如果已知被占用的端口时,可以用命令netstat-aon|findstr8109直接找到端口号为7009的进程,PID为36304 netstat-aon|findstr8019 3) 根据PID进......
  • .NET开源免费的跨平台框架 - MAUI(附学习资料)
    前言前几天分享了一个.NETMAUI开源免费的UI工具包-Uranium,然后技术群有不少同学问.NETMAUI是不是免费的?能做什么?今天特意写这篇文章来介绍一下.NET开源、免费(基于MITLicense)的跨平台框架:MAUI。.NETMAUI官方介绍.NET多平台应用UI(.NETMAUI)是一个跨平台框架,用于使用......
  • Asp-Net-Core开发笔记:使用alpine镜像并加入健康检查
    前言使用docker部署AspNetCore应用已经是标配了,之前我一直使用mcr.microsoft.com/dotnet/aspnet:8.0这类镜像,简单粗暴,不过可以使用alpine进一步优化镜像大小。很多开源工具的docker都有健康检查,这次我顺便也给加上了。添加健康检查注册服务builder.Services.AddHea......