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();
[HttpGet]
public
IEnumerable<``string``> Get()
{
return
new
string``[] {
"value1"``,
"value2"
};
}
[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;
}
[HttpPost]
public
void
Post([FromBody]``string
value)
{
}
[HttpPut(``"{id}"``)]
public
void
Put(``int
id, [FromBody]``string
value)
{
}
[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``; }
public
void
ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
{
if
(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
lifetime.ApplicationStarted.Register(OnStart);
lifetime.ApplicationStopped.Register(UnRegService);
}
private
void
OnStart()
{
LoadAppConfig();
RegService();
}
private
void
LoadAppConfig()
{
Console.WriteLine(``"ApplicationStarted:LoadAppConfig"``);
}
private
void
RegService()
{
Console.WriteLine(``"ApplicationStarted:RegService"``);
}
private
void
UnRegService()
{
Console.WriteLine(``"ApplicationStopped:UnRegService"``);
}
}
}
5、在程序根目录运行dotnet run
访问: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);
lifetime.ApplicationStopped.Register(UnRegService);
}
3、运行程序,用postman发起一个head请求,请求头中加
{
Stop-Application:Yes
}
详细说明可参考:https://www.cnblogs.com/artech/p/application-life-time.html