• ASP.NET Core应用到Windows Service中


    托管到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

    使用它也很简单:

    1. 创建一个以.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本身就支持一个项目多个运行时的)
    2. 引用Microsoft.AspNetCore.Hosting.WindowsServices。--此包是.Net Framework的
    3. 在Program的Main方法中,把默认的host.Run改为host.RunAsService。
    4. 编译程序后,会在Debug目录下看到你选用的运行时版本的一个目录,比如“net46”,在里面会看到编译好的exe文件和一个类似“win7-x64”的这样文件夹。
    5. 进入到“win7-x64”文件夹,在命令行执行“sc create MyService binPath = "FullPathToTheConsolefile.exe --windows-service”(必须加参数,否则启动服务报1053错误),来创建一个Windows Service。注意:binPath必须是全路径。
    6. 这样就可以在Windows Service中托管ASP.NET Core应用了。
    7. 如果希望在服务启动和停止的过程中做一些额外处理,比如记录日志,那么可以实现一个CustomWebHostService来继承WebHostService ,并在其中编写所需的代码。
    8. 并实现如下的扩展方法:
    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个问题要解决其实也非常简单。

    支持不同启动方式

    第二个问题的解决办法如下:

    1. 在Program的Main方法中,判断一下特定的命令行参数,比如“--windows-service”
    2. 以这个参数启动的情况下,就host.RunAsService,不是的话就host.Run。

    就是这么简单粗暴。

    支持不同运行时

    .NET Core本来就支持一个项目多个运行时,就算把net46和netcoreapp1.0混合也是可以的。具体方法如下:

    1. 修改project.json文件,在frameworks下额外添加“netcoreapp1.0”。
    2. 把对Microsoft.AspNetCore.Hosting.WindowsServices的依赖移到net46下
    3. 在netcoreapp1.0下添加“Microsoft.NETCore.App”的依赖
    4. 在Program的Main方法中,基于条件编译的符号来判断不同的运行时,具体的符号表见:https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/libraries#how-to-multitarget

    示例源代码

    为了避免在文章中贴大段的源代码,大家转到GitHub中去看示例代码吧:https://github.com/heavenwing/HostingAspCoreAsWindowsService

  • 相关阅读:
    Django进阶之session
    Windows下MySQL下载安装、配置与使用
    Windows下安裝並設置Redis
    mysql root密码忘记
    .net core 持续构建简易教程
    SqlServer简单数据分页
    产品规划之战略规划;
    C#Excel文件加密实现,支持xlsx、docx、pptx(C#NetAsp.Net)
    仿QQ空间根据位置弹出PopupWindow显示更多操作效果
    Windows编译Nginx源码
  • 原文地址:https://www.cnblogs.com/8090sns/p/8086484.html
Copyright © 2020-2023  润新知