最近在測試ASP.NET core上的IHostedService製作的schedule task ,發現了一個tricky的問題。
問題描述如下:
在Startup.cs中的ConfigureServices() 裡我們會加上要重複執行的schedule
task (IHostedService),預期網站運行後開始背景執行這些task,但實際在IIS上測試發現兩個問題:
1. schedule task並不會自動執行,除非對網站進行訪問(任何http request),例如開啟首頁。這時那些在ConfigureServices()加入的task才會被建立並且開始運作。
2. 如果一直都沒有對網站進行訪問(任何http request),約20分鐘後所有task都會停止,直到下一次網站被訪問(任何http request)才會又開始所有task
。
基於以上兩點行為,針對第一點,我們的網站必須要每次主機開機都開一次首頁或是任何對網站的request,否則schedule task不會執行。針對第二點,我們需要確保固定時間對網站進行訪問(任何http request),目前的作法是每次task執行時就發個request。(如果schedule task本來就會發API request就沒問題)
ASP.NET Core的IHostedService運作行為:
這個問題目前的了解是:以IHostedService製作的schedule task,它的生命週期開始在Web server接收到任何一個http request的時候,而IIS運行Web server時並不會觸發http request,所以schedule task也就不會啟動。再來另一個狀況是,IIS有個預設的idle timeout機制,即使schedule task啟動了,如果一直都沒有對網站進行訪問(任何http request),20分鐘後會將Web server的http實體程序關閉,所以schedule task也就停止了。
非透過IIS的解決方式:
在Server開機後透過固定開啟網站首頁的方式,讓schedule task啟動,並加入一個schedule task固定每10分鐘對Web server發送一個http request,以確保IIS不會將schedule task停止。
透過IIS的解決方式:
在IIS管理介面上可以設定,將Web server的行為設成每次server運行時就載入主體程序。經測試可以解決IHostedService製作的schedule task不會自行啟動的問題,另外即使IIS預設的idle timeout時間到了,也會自動重啟新的主體程序,schedule task不會停止。
設定步驟如下:
[設定自動背景執行]
[控制台]-->[程式和功能]-->[開啟或關閉windows功能] à打勾 應用程式初始化
如下圖,在IIS管理員中進入[進階設定]
將[預先載入已啟用]設為True
到[應用程式集區],的[進階設定]
如下圖,將[啟動模式]設成 AlwaysRunning
至此完成設定
留言
張貼留言