前情提要
筆者最近因工作上需要使用到排程及背景服務,類似像定期傳送Email或者定時做某一項作業,當然筆者最近在工作上使用皆以全部換成.net core
的技術,因此選擇上以.net core
技術可達成的方式來完成,會有幾種選擇:
寫一個
Console Application
,搭配使用Windows排程設定讓該exe
檔於特定時間執行.net core一直以來都有一個藉由實作
IHostedService
來達成背景服務,參考.net core 3.0後更是有
Worker Service
專案範本可以使用,可以藉由此類專案來實作背景服務,比起.net core 2.*,更是方便使用
以上幾種選擇,因不同專案及使用情境,選擇不一樣的選項來達成,針對這篇文章解決的問題,使用情境則是一個Web API
小專案,因考量上版及管理方便,直接於既有Web API
專案上使用排程套件 Coravel
或Hangfire
來完成排程作業,或者使用CAP
。
套件使用方式參考筆者其他專門介紹套件的文章,在此不贅述,程式開發完後發佈於IIS
上,觀察log一段時間後會發現,IIS
上應用程式集區預設設定之閒置時間20分鐘一到後,若沒有任何活動則會被IIS Application Pool
強制回收執行緒,此時背景服務是被中斷的,止到使用者連線使用服務,背景服務才會被再次啟動。
內容
IIS設定調整
上段描述對於背景服務要定期執行某項作業的健全性是危害的,假設這Web API
服務為內部系統,因此週休二日時上線使用者人數幾呼為零,在此狀況下,原本設定好週末時運行一段排程作業,會因IIS Application Pool
強制回收執行緒而中斷。要解這問題就要從IIS
設定上面著手,需要調整IIS
的應用程式集區中的進皆設定,主要修改的設定為
Start Mode(啟動模式)
設定為Always Running
,預設為On Demand
Idle Time-out(minutes)限制時間(分)
設定為0
,預設為20
接著也要針對站台的進階設定中調整
Preloaded Enabled(預先載入已啟用)
設定為True
,預設為False
當然,上述這些方法可以解決運行中的IIS服務不會被中斷,但必須得保證IIS服務已被第一個Request而啟動,因此更新過程式版本,若使用停止IIS後重新起動這種更新模式則,切記需手動打開(觸發)那個站台的某一個頁面或服務,使得確保背景服務被啟動,這樣的解決方式才會完美無缺了。
安裝應用程式初始化
非常重要的一個步驟,判斷為回收停止後,應用程式可自行啟動並初始化,會看到Shut Down後又Started紀錄。
結論
最後,若使用IIS架排程站台,需要設定上述的步驟,才不會被雷到,也由此可知,IIS設定也是一門學問,僅此紀錄其設定,若有碰到其他相關設定技巧,筆者會在寫文章說明。
參考
- https://blog.darkthread.net/blog/hangfire-recurringjob-notes/
- https://github.com/dotnetcore/CAP/issues/406
- https://rules.ssw.com.au/do-you-ensure-your-application-pool-is-always-running
- https://dotblogs.com.tw/rainmaker/2015/08/27/153232