背景:項目各個模塊部署在不同位置,因此采用了微服務架構。由於安裝部署環境的差異,部分模塊只能部署在xp系統下,其他部署環境考慮使用net.core,在windows服務中托管webapi,或者在webapi中寄宿windows服務,總而言之就是在一個程序中將windows服務和webapi結合起來。
項目中使用了兩種將windows服務和webapi結合起來的方法、框架。一種是通過Topshelf,將控制台程序作為windows服務安裝,同時將webapp啟動的webapi寄宿到控制台程序中;第二種就是使用asp.net.core,托管到windows服務中。
方法一:topshelf、控制台的方式。
1.創建一個控制台應用程序,建議使用framework,據說某版本的topshelf不兼容netcore(未驗證)。
2.在main方法中使用以下代碼。ServicesHost為自定義類,無其他父類。只需要實現其構造方法、服務開始方法、服務結束方法即可。如此即可將一個控制台程序作為windows服務來使用。關於服務的安裝卸載,請自行查看topshelf,太簡單不再贅述。
HostFactory.Run(x => { x.Service<ServicesHost>(s => { s.ConstructUsing(name => new ServicesHost()); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); x.RunAsLocalSystem(); x.StartAutomaticallyDelayed(); x.SetDescription(“服務描述”); x.SetDisplayName(“顯示名稱”); x.SetServiceName(“服務名稱”);//注意不要使用特殊字符 });
3.在ServicesHost的適當位置使用WebApp,為webapi指定端口。
WebApp.Start(string.Format("http://*:{0}", ConfigHelper.Instance.WebPort));
4.自定義控制器,繼承ApiController。在控制器上添加RoutePrefix屬性或者Route來進行路徑控制。系統部署后即可實現將webapi托管到windows服務中。
方法二:在windows服務中托管asp.net.core。
1.創建一個asp.net.core webapplication 項目。
2.在program配置service。 注意:2、4中的代碼應在CreateHostBuilder鏈式實現。
Host.ConfigureServices((host,services)=>{serices.AddHostedService<T where T:BackgroundService>()});
3.自定義服務類T,繼承BackgroundService,可以重寫StartAsync、ExecuteAsync、StopAsync方法。在execute執行服務內容。
4.配置host的默認配置,主要是指定端口號。
Host.ConfigureWebHostDefaults(webBuilder => { webBuilder .UseUrls("http://*:5001", "http://*:5002")//配置監聽端口 .UseStartup<Startup>() .UseKestrel();//指定托管服務器,Kestrel 或者iis服務器都可以,推薦使用Kestrel,可以在無iis的環境使用。 });
5.路由的使用。微軟的推薦方式是使用了Route屬性,在屬性內添加控制器的路由模板。如果想用rest風格,不妨在Route屬性自定義模板,通俗點說就是每個控制器都自己有個模板,看起來比較麻煩點但也保證了控制器的靈活性。 eg:
[Route("[controller]")] // 訪問路徑: http://127.0.0.1:5002/WeatherForecast public class WeatherForecastController : ControllerBase{} [Route("api/[controller]")] 訪問路徑: http://127.0.0.1:5002/api/WeatherForecast public class WeatherForecastController : ControllerBase{}
總結:根據實際情況使用如果是考慮跨平台,就用第二種。如果系統環境限制可以考慮使用第一種,都各有優劣。