托管到Windows Service中
众所周知,ASP.NET Core采用了和传统ASP.NET不同的托管和HTTP处理方式,即把服务器和托管环境完全解耦。
ASP.NET Core内置了两个HTTP服务器实现,一个是基于libuv实现的Kestrel(支持跨平台),一个是基于Windows HTTP Server API实现的WebListener(仅支持Windows)。
而托管环境可以和服务器不相关,一般情况是自托管,或者托管到IIS/IISExpress中(此处的IIS仅作为反向代理把请求转发给所使用的服务器实现)。
因此,打算以Windows Service这种比较传统的方式来部署ASP.NET Core的Web应用也是可行的(本质还是自托管,只是启动进程并非控制台程序,而是一个Windows Service)。这不,微软就很贴心的提供了一个Nuget来支持:Microsoft.AspNetCore.Hosting.WindowsServices,它的源码在:https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices。
使用它也很简单:
- 创建一个以.NET Framework为运行时的ASP.NET Core应用,即模版选择“ASP.NET Core Web Application (.NET Framework)”。VS2017中没有此模板,可以选择框架为.NET Framework4.6,模板为ASP.NET Core Web Application,然后编辑项目文件,修改TargetFramework为“<TargetFramework>net461;netcoreapp2.0</TargetFramework>”,这样编译出来就是两个框架的(NetCore本身就支持一个项目多个运行时的)
- 引用Microsoft.AspNetCore.Hosting.WindowsServices。--此包是.Net Framework的
- 在Program的Main方法中,把默认的host.Run改为host.RunAsService。
- 编译程序后,会在Debug目录下看到你选用的运行时版本的一个目录,比如“net46”,在里面会看到编译好的exe文件和一个类似“win7-x64”的这样文件夹。
- 进入到“win7-x64”文件夹,在命令行执行“sc create MyService binPath = "Full\Path\To\The\Console\file.exe --windows-service”(必须加参数,否则启动服务报1053错误),来创建一个Windows Service。注意:binPath必须是全路径。
- 这样就可以在Windows Service中托管ASP.NET Core应用了。
- 如果希望在服务启动和停止的过程中做一些额外处理,比如记录日志,那么可以实现一个CustomWebHostService来继承
WebHostService
,并在其中编写所需的代码。 - 并实现如下的扩展方法:
public static class CustomWebHostWindowsServiceExtensions
{
public static void RunAsCustomService(this IWebHost host)
{
var webHostService = new CustomWebHostService(host);
ServiceBase.Run(webHostService);
}
}
host.RunAsCustomService();
把ASP.NET Core应用托管到Windows Service中,就这么简单!
更多问题?
不过,我想从我的场景来谈谈为什么我有托管到Windows Service的需求。这几天在构思一个中间件(包含多个组件)的架构,考虑到初期会以比较传统的方式来部署,后期有可能跨平台,并且希望组件之间能够相对独立和解耦。所以,最自然的想法就是架构设计为微服务,基于ASP.NET Core实现(未来不排除使用其他技术栈)。部署的话,初期分离部署为多个Windows Service,后期也可以很平滑的过度到容器或者类似Service Fabric这样的微服务运行平台中。
基于这样的设计考虑,要解决的第一个问题就是是否可以把ASP.NET Core应用托管到Windows Service中(上面已经验证了),第二个问题是是否可以根据环境条件跑在不同的启动进程中,第三问题是是否可以同时支持多种运行时。2,3个问题要解决其实也非常简单。
支持不同启动方式
第二个问题的解决办法如下:
- 在Program的Main方法中,判断一下特定的命令行参数,比如“--windows-service”
- 以这个参数启动的情况下,就host.RunAsService,不是的话就host.Run。
就是这么简单粗暴。
支持不同运行时
.NET Core本来就支持一个项目多个运行时,就算把net46和netcoreapp1.0混合也是可以的。具体方法如下:
- 修改project.json文件,在frameworks下额外添加“netcoreapp1.0”。
- 把对Microsoft.AspNetCore.Hosting.WindowsServices的依赖移到net46下
- 在netcoreapp1.0下添加“Microsoft.NETCore.App”的依赖
- 在Program的Main方法中,基于条件编译的符号来判断不同的运行时,具体的符号表见:https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/libraries#how-to-multitarget
示例源代码
为了避免在文章中贴大段的源代码,大家转到GitHub中去看示例代码吧:https://github.com/heavenwing/HostingAspCoreAsWindowsService
ASP.NET Core应用到Windows Service中的更多相关文章
-
如何托管ASP.NET Core应用到Windows Service中
(此文章同时发表在本人微信公众号"dotNET开发经验谈",欢迎右边二维码来关注.) 题记:正在构思一个中间件的设计,考虑是否既可以使用最新的技术,也可以兼顾传统的部署模式.所以有 ...
-
ASP.NET Core在Azure Kubernetes Service中的部署和管理
目录 ASP.NET Core在Azure Kubernetes Service中的部署和管理 目标 准备工作 注册 Azure 账户 AKS文档 进入Azure门户(控制台) 安装 Azure Cl ...
-
NetCore Selfhost,IIShost,Windows Service Host详解(自宿主、宿主在IIS,宿主在Windows Service中)
第一部分.自托管 一.依赖.Net Core环境 修改 project.json 文件内容,增加发布时需要包含文件的配置内容(NetCore2.0版本不需要任何设置,NetCore2.0开始彻底放弃p ...
-
asp.net core 托管到windows服务,并用iis做反向代理
使用NSSM把.Net Core部署至 Windows 服务 为什么部署至Windows Services 在很多情况下,很少会把.Net Core项目部署至Windows服务中,特别是Asp.n ...
-
ASP .NET CORE MVC 部署Windows 系统上 IIS具体步骤---.Net Core 部署到 IIS位系统中的步骤
一.IIS 配置 启用 Web 服务器 (IIS) 角色并建立角色服务. 1.Windows Ddesktop 桌面操作系统(win7及更高版本) 导航到“控制面板” > “程序” > “ ...
-
尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性
本文首发于<尝新体验ASP.NET Core 6预览版本中发布的最小Web API(minimal APIS)新特性> 概述 .NET开发者们大家好,我是Rector. 几天前(美国时间2 ...
-
ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成
ASP.NET Boilerplate 学习 1.在http://www.aspnetboilerplate.com/Templates 网站下载ABP模版 2.解压后打开解决方案,解决方案目录: ...
-
ASP.NET Core 新建项目(Windows) - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 新建项目(Windows) - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 新建项目(Windows) 对于任何语言和框架,都 ...
-
Windows Service中使用Threading.Timer需注意回收
在Windows Service中使用Threading.Timer时需要注意回收池问题 Threading.Timer是基于线程池的,系统会对其进行垃圾回收. 当Threading.Timer定义在 ...
随机推荐
-
【实践】js 如何实现动态添加文本节点
对于我这个js 小白来说 今天鼓起勇气做起了邮箱认证这个特效 但是这次不是想说如何实现这这个特效而是想记录一下特效当中的某个部分 那就是向元素节点动态添加文本节点 百度了一下动态添加文本节点的方式 是 ...
-
《我是一只IT小小鸟》读后感
过了半个学期的大学生活,说实话,我是迷茫的,因为我还没有足够的了解IT这门课程,也不知道怎么学好这门课程. 直到老师推荐我们读一本书<我是一只it小小鸟>,起初,我并不认为它是一本多么好的 ...
-
python随文档
UNIX网络编程--socket的keep http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html 云计算学习和实践: 原创<每 ...
-
URL的语法及HTTP报文
大多数URL方案的URL语法都建立在这个由9部分构成的通用格式上: scheme://user:password@host:port/path;params?query#frag 方案:http或者h ...
-
Oracle_Q&;A_01
Step01: SHOW USER DESCRIPTION Step02:QUESTION & ANSWER --查询员工姓名和职位字数相等的员工 SELECT * from emp wher ...
-
TypeScript基本知识(为学习AngularJS2框架做个小铺垫)
学习angularjs2框架,需要了解一些TypeScript知识点,基本了解下面这几个知识点学习AngularJS2 就够用了 1.TypeScript 1.1显示类型的定义 TypeScript类 ...
-
Struts网站基于Filter的XSS漏洞修复
下面的代码只支持struts2框架中的xss漏洞 第一步,创建过滤器XssFilter : package com.ulic.ulcif.filter; import java.io.IOExcept ...
-
Flutter之搜索电影
搜索使用的是豆瓣电影API https://developers.douban.com/wiki/?title=movie_v2#subject 效果 代码: https://github.com/z ...
-
使用springmvc从页面中获取数据,然后根据获得的参数信息进行修改,如果修改的数据中含有不是基本数据类型的参数。比如传的参数中有Date类型的数据时,需要我们进行参数类型转换。
1.1 需求 在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式. 1.2 需求分析 由于日期数据有很多格式,所以springmvc没办法把字符串转换成日期类型.所以需要自定义参数绑 ...
-
MVC中导航菜单,选中项的高亮问题。。
先上图: 这个菜单是放在母板页的.比如当前选中的是异常业务监控.如果页面刷新了.就会变成第一张图..选择其他的选项也会,因为页面会刷新嘛.. 怎么处理这个问题了? 答案是记录当 ...