一、背景
NetCore作为微服务可以注册到服务中心,服务中心可以远程启动、重启、关闭该微服务
二、实现
1、创建一个NetCore 2.0 WebApi项目
2、创建一个进程去管理NetCore程序进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static void Main( string [] args) { try { var appManager = ApplicationManager.Load(); do { appManager.Start(); } while (appManager.Restarting); } catch (Exception ex) { } } |
4、在程序的ValuesController中实现重启、关闭的Api
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
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、给程序启动和停止加入日志标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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、注册中间件
1
2
3
4
5
6
7
8
9
10
11
12
|
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
本博客Android APP 下载 |
支持我们就给我们点打赏 |
支付宝打赏 支付宝扫一扫二维码 |
微信打赏 微信扫一扫二维码 |
如果想下次快速找到我,记得点下面的关注哦!