一、背景

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

Asp.NetCore远程自启动、重启、关闭实现的更多相关文章

  1. powershell 远程重启/关闭服务器

    powershell 远程重启/关闭服务器 #启动winrm PS C:\Windows\system32> winrm quickconfig -q #设置信任主机 PS C:\Windows ...

  2. Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一)

    环境 本地 win7 服务器:Virtual Box 上的Centos ssh工具: Xshell 文件传输: xftp 1.在本地创建asp.net core应用发布 1.1 使用Vs2017 新建 ...

  3. Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践

    原文:Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践 环境 本地 win7 服务器:Virtual Box 上的Centos ssh工具: Xshell 文件传输 ...

  4. oracle 配置 自启动 和 关闭

    今天在看oracle自启动脚本,突然有点时间,总结一下!!! 第一次写博客,大家随便看看就好,有错误麻烦提醒下,不喜欢别喷,主要是锻炼自己,形成写博客的好习惯. 刚毕业,现在还没转正,在干运维和自学d ...

  5. Asp.NetCore轻松学-使用Supervisor进行托管部署

    前言 上一篇文章 Asp.NetCore轻松学-部署到 Linux 进行托管 介绍了如何在 Centos 上部署自托管的 .NET Core 应用程序,接下来的内容就是介绍如何使用第三方任务管理程序来 ...

  6. Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(二)

    Asp.NetCore程序发布到CentOs(含安装部署netcore)--最佳实践(一) 接上一篇 3. Nginx配置反向代理 3.1 cnetos 安装nginx 首先,我们需要在服务器上安装N ...

  7. 使用PowerShell自动部署ASP.NetCore程序到IIS

    Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能.有关于更多PowerShell的信息,可参阅百度词条 接 ...

  8. Asp.Net 远程连接Oracle数据库

    Asp.Net 远程连接Oracle数据库 首先从微软停止.Net FrameWork支持Oracle数据库的研发,转为第三方提供说起,微软是很有实力的公司,他在桌面领域令其他对手望其项背,产品战线也 ...

  9. ASP.NETCore使用AutoFac依赖注入

    原文:ASP.NETCore使用AutoFac依赖注入 实现代码 1.新建接口类:IRepository.cs,规范各个操作类的都有那些方法,方便管理. using System; using Sys ...

随机推荐

  1. 关于bind named.conf.options

    /etc/named/named.conf.options中的Options参数   listen-on port 53 { any; }; 监听在这部主机系统上面的哪个网路介面.预设是监听在loca ...

  2. Javascript+CSS实现影像卷帘效果

    用过Arcgis的筒子们对于Arcmap里面的一个卷帘效果肯定记忆很深刻,想把它搬到自己的WebGIS系统中去,抱着同样的想法,我也对这种比较炫的卷帘效果做了一下研究,吼吼,出来了,给大家汇报一下成果 ...

  3. Android 如何快速生成aar?

    aar主要分为两步 第一步 新建一个Module类似于Eclipse中的project 然后AddLibrary然后点击Finish完成 生成mylibrary-debug.aar文件 然后将.aar ...

  4. 在linux中使用shell来分析统计日志中的信息

    在运维工作中,要经常分析后台系统的日志,通过抓取日志中的关键字信息,对抓取结果进行统计,从而为监控结果提供基础数据.下面的shell演示了如何从大量的日志中取得想要的统计结果.其中展示了各种有趣的命令 ...

  5. HDU - 4333 :Revolving Digits (扩展KMP经典题,问旋转后有多少个不同的数字小于它本身,等于它本身,大于它本身。)

    One day Silence is interested in revolving the digits of a positive integer. In the revolving operat ...

  6. python之pandas数据筛选和csv操作

    本博主要总结DaraFrame数据筛选方法(loc,iloc,ix,at,iat),并以操作csv文件为例进行说明 1. 数据筛选 a b c (1)单条件筛选 df[df[] # 如果想筛选a列的取 ...

  7. 【eclipse新增系列】eclipse新安装设计编码统一

  8. linux上编写运行 dotnet core api

    安装 Ubuntu        dotnet core 跨平台已不再是梦,它带来的意义非凡,比如api接口可以在linux上编写及部署,也可以在windows上编写好,打包发布,然后copy到lin ...

  9. python 爬虫的一些使用技巧

    1.最基本的抓站 import urllib2 content = urllib2.urlopen('http://XXXX').read() -2.使用代理服务器这在某些情况下比较有用,比如IP被封 ...

  10. [Luogu1527][国家集训队]矩阵乘法

    luogu 题意 给你一个\(N*N\)的矩阵,每次询问一个子矩形的第K小数.(居然连修改都不带的) \(N\le500,Q\le60000\) sol 整体二分+二维树状数组裸题. 复杂度是\(O( ...