zoukankan      html  css  js  c++  java
  • Asp.NetCore远程自启动、重启、关闭实现

    一、背景

    NetCore作为微服务可以注册到服务中心,服务中心可以远程启动、重启、关闭该微服务

    二、实现

    1、创建一个NetCore 2.0 WebApi项目

    2、创建一个进程去管理NetCore程序进程

    public class ApplicationManager
        {
    
            private static ApplicationManager _appManager;
            private IWebHost _web;
            private CancellationTokenSource _tokenSource;
            private bool _running;
            private bool _restart;
    
            public bool Restarting => _restart;
    
            public ApplicationManager()
            {
                _running = false;
                _restart = false;
            
            }
    
            public static ApplicationManager Load()
            {
                if (_appManager == null)
                    _appManager = new ApplicationManager();
    
                return _appManager;
            }
    
            public void Start()
            {
                if (_running)
                    return;
    
                if (_tokenSource != null && _tokenSource.IsCancellationRequested)
                    return;
    
                _tokenSource = new CancellationTokenSource();
                _tokenSource.Token.ThrowIfCancellationRequested();
                _running = true;
    
                _web = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();
    
                _web.Run(_tokenSource.Token);
            }
    
            public void Stop()
            {
                if (!_running)
                    return;
    
                _tokenSource.Cancel();
                _running = false;
            }
    
            public void Restart()
            {
                Stop();
    
                _restart = true;
                _tokenSource = null;
            }
        }
    

      3、把ApplicationManager加入到Main中

    public static void Main(string[] args)
            {
                try
                {
                    var appManager = ApplicationManager.Load();
    
                    do
                    {
                        appManager.Start();
                    } while (appManager.Restarting);
    
    
                }
                catch (Exception ex)
                {
    
                }
            }
    

      4、在程序的ValuesController中实现重启、关闭的Api

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    
    namespace NetCoreWebApiDemo.Controllers
    {
        [Route("api/[controller]")]
        public class ValuesController : Controller
        {
            private ApplicationManager appManager = ApplicationManager.Load();
    
            // GET api/values
            [HttpGet]
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
    
            // GET api/values/5
            [HttpGet("{cmd}")]
            public string Get(string cmd)
            {
                switch (cmd)
                {
                    case "restart": appManager.Restart(); break;
                    case "stop": appManager.Stop(); break;
                    case "start": appManager.Start(); break;
                }
                return cmd;
            }
    
    
    
            // POST api/values
            [HttpPost]
            public void Post([FromBody]string value)
            {
            }
    
            // PUT api/values/5
            [HttpPut("{id}")]
            public void Put(int id, [FromBody]string value)
            {
            }
    
            // DELETE api/values/5
            [HttpDelete("{id}")]
            public void Delete(int id)
            {
            }
        }
    }
    

    6、给程序启动和停止加入日志标签

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace NetCoreWebApiDemo
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseMvc();
    
                lifetime.ApplicationStarted.Register(OnStart);//1:应用启动时加载配置,2:应用启动后注册服务中心
                lifetime.ApplicationStopped.Register(UnRegService);//应用停止后从服务中心注销
            }
            private void OnStart()
            {
                LoadAppConfig();
                RegService();
            }
            private void LoadAppConfig()
            {
                //加载应用配置
                Console.WriteLine("ApplicationStarted:LoadAppConfig");
            }
    
            private void RegService()
            {
                //先判断是否已经注册过了
                //this code is called when the application stops
                Console.WriteLine("ApplicationStarted:RegService");
            }
            private void UnRegService()
            {
                //this code is called when the application stops
                Console.WriteLine("ApplicationStopped:UnRegService");
            }
        }
    }
    

      

      

    5、在程序根目录运行dotnet run

    访问:http://localhost:51062/api/values,显示:["Value1","Value2"]

    访问:http://localhost:51062/api/values/restart:显示restart,再访问http://localhost:51062/api/values正常返回["Value1","Value2"]

     

    访问:http://localhost:51062/api/values/stop,显示:stop,再访问http://localhost:51062/api/values就是404了

    stop后由于netcore进程已经被关闭,没有了http监听,通过url方式是无法重新启动了,这里可以借助类似supervisor的工具来停止进程,启动进程。

    三、源码地址

     https://github.com/andrewfry/AspNetCore-App-Restart

    四、其它实现

    1、除了上面,还可以通过中间件的形式,实现远程关闭

    新增一个中间件的类:

    public class RemoteStopMiddleware
        {
            private RequestDelegate _next;
            private const string RequestHeader = "Stop-Application";
            private const string ResponseHeader = "Application-Stopped";
    
            public RemoteStopMiddleware(RequestDelegate next)
            {
                _next = next;   
            }
        
           public async Task Invoke(HttpContext context, IApplicationLifetime lifetime)
           {
               if (context.Request.Method == "HEAD" && context.Request.Headers[RequestHeader].FirstOrDefault() == "Yes")
              {
                   context.Response.Headers.Add(ResponseHeader, "Yes");
                 lifetime.StopApplication();
               }
               else if (context.Request.Method == "HEAD" && context.Request.Headers[RequestHeader].FirstOrDefault() == "No")
                {
                    context.Response.Headers.Add(ResponseHeader, "No");
                    // See you on the next request.
                    //Program.Shutdown();
                }
                else
               {
                   await _next(context);
               }
           }
        }

    2、注册中间件

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseMvc();
                app.UseMiddleware<RemoteStopMiddleware>();
                lifetime.ApplicationStarted.Register(OnStart);//1:应用启动时加载配置,2:应用启动后注册服务中心
                lifetime.ApplicationStopped.Register(UnRegService);//应用停止后从服务中心注销
            }
    

    3、运行程序,用postman发起一个head请求,请求头中加

    {

    Stop-Application:Yes

    }

    详细说明可参考:https://www.cnblogs.com/artech/p/application-life-time.html

  • 相关阅读:
    分支(选择)语句练习——7月22日
    语句:分支语句、switch case ——7月22日
    C#语言基础——7月21日
    进制转换——7月20日
    运行Tomcat报错 解决方法
    Mybatis面试题
    java面试题02
    当你没有能力去改变别人命运的时候 就不要随意去伸出援手......
    快速学习MD5的方法
    java面试题01
  • 原文地址:https://www.cnblogs.com/8090sns/p/8086828.html
Copyright © 2011-2022 走看看