0%

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/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);

lifetime.ApplicationStopped.Register(UnRegService);

}

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

{

Stop-Application:Yes

}

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