一、背景

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. 剑指offer--24.树的子结构

    时间限制:1秒 空间限制:32768K 热度指数:407165 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)   class Solution ...

  2. 【git】项目更新方法

    [放弃修改] 工作区 -- 暂存区 -- 本地仓库 -- 远程仓库 工作区 -- 暂存区: git diff git checkout .  /  git reset --hard 暂存区 -- 本地 ...

  3. Lua基础---运算符

    众所周知,C,C++,python等语言都有运算符,那么Lua也不例外,因为它是C写的嘛! Lua分为主要三类运算符,分别是算术运算符,关系运算符,逻辑运算符,还有特殊运算符. 1.算术运算符有: + ...

  4. Failed to export application

    打包Android项目,遇到Failed to export application的错误提示.如何处理呢 我当时是 在替换图标时   没有完全替换 只替换了 四张drawable_h图片,没有替换上 ...

  5. 数据结构之最小生成树Kruskal算法

    1. 克鲁斯卡算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个 ...

  6. ExpressionTree,Emit,反射

    ExpressionTree,Emit,反射 https://www.cnblogs.com/7tiny/p/9861166.html [前言] 前几日心血来潮想研究着做一个Spring框架,自然地就 ...

  7. 并发问题 关于Redis

    并发问题 关于Redis [吐槽]Jimesembria 付费请人解这个BUG , 有没有php同学有兴趣,(问题原因是理论上是5分钟内不生产同样金额的订单, 但是由于并发原因没控制好) 10:34: ...

  8. android jUnit test 进行自动化测试

    一. 被test的工程: 新建一个android工程:D_session:它有一个activity:D_sessionActivity:package名:com.mysession 二.测试工程: 新 ...

  9. 安装nagios-plugins插件make时遇到的error

    安装nagios-plugins插件make时遇到的error error内容: check_http.c: In function ‘process_arguments’: check_http.c ...

  10. ADO+MFC数据库编程常用语句

    设在OnInitDialog()函数中,已经完成了初始化COM,创建ADO连接等操作,即 // 初始化COM,创建ADO连接等操作 if (!AfxOleInit()) { AfxMessageBox ...