2

【茶包射手日記】IIS的29小時魔咒

 2 years ago
source link: https://blog.darkthread.net/blog/iis-app-pool-auto-recycle/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【茶包射手日記】IIS的29小時魔咒

2014-04-07 07:48 AM 3 57,363

趁著假日對一台ASP.NET MVC網站進行長時間壓測,初期數據表現不俗,顯示調校策略奏效,放著讓程式跑測試穩定性。中午因事外出,回家後馬上檢查系統是否穩定,登楞! 測試畫面顯示Web Application已重啟… orz

猜想是程式寫法有問題導致Crash,心頭涼了半截,沮喪地檢查IIS主機的事件檢視器,想找出ASP.NET錯誤或IIS Crash的線索,卻發現以下記錄:

2137-6e38-o.gif

A worker process with process id of 'xxx' service application pool 'zzz' has requested a recyle because the worker process reached its allowed processing time limit.

因為工作者處理序已達到允許的處理時間上限,所以伺服應用程式集區 'zzz' 且處理序識別碼為 'xxx' 的工作者處理序已要求回收。

哈! 原來不是程式當掉,而是Application Pool(應用程式集區)被IIS強制回收導致重啟。一則以喜,一則以憂,喜的是程式沒錯,不需要抓Bug ^_^;憂的是自己的IIS經驗不及格,無法一眼看出這是什麼妖魔鬼怪? orz

抱著慚愧的心情查文件,整理筆記如下:

從IIS6起,就有定期重啟Application Pool機制,以解決程式跑久可能出現記憶體洩漏(Memory Leaking,指記憶體用完沒歸還,導致可用記憶體愈來愈少)或其他稀奇古怪的問題,這類疑難雜症通常在重新啟動程序後就會一掃而空。但,這是那門子鴕鳥心態? 程式沒寫好不是該徹底抓漏除盡一切Bug嗎? 靠重開逃避問題算什麼男子漢?

的確,天下沒有抓不到的Bug,端看你願意付出多少心血跟它對抗,無奈人生苦短、老闆/客戶耐心有限! 花上半年反覆實驗,靠奇技淫巧解開程式持續跑三天當機之謎,其興奮度勝過拿下NBA總冠軍,這點我絕對相信。但是,若放任正式系統不穩超過一星期,開發團隊早已萬箭穿心。更何況機房、系統裡常存在人類至今無法理解的神祕力量(不然機房也不會有那麼多"乖乖傳奇"),如果3R(Reset、Restart、Reinstall)可以立刻解決又不傷身體,何苦跟自己過不去? 要追根究底不是不行,把戰場拉回實驗室再談成長學習,正式環境還是得求快速解決問題。

於是,IIS有定期回收(Recyling)機制,預設每29小時(1740分鐘)回收Worker Process。莫非我就是中了IIS 29小時魔咒? 由IIS Log證實了這點:

2138-0c3c-o.gif

由回收時間4/4 12:50向前推29小時,為4/3 07:50,換成UTC時間為4/2 23:50,Bingo!!

任意回收Worker Process,難道不會影響線上服務? IIS設想周到,回收前會先悄悄另起新的Worker Process,開始接收Request,現有Process則會等到進行中的Request完成再下線,達到無縫接軌的效果(稱為Overlapped Recycle)。如果網站程式被設計成Stateless(無狀態,指IIS主機本身不保存任何狀態資料),切換過程如同Web Farm裡換一台主機連線,使用者是完全無感的。但我的專案並非Stateless,一旦切換主機,儲存於記憶體中的資料遺失,前端就必須重新初始化才能繼續運作。換句話說,如果專案非Stateless,就會遇到每隔29小時程序無故重啟、狀態遺失的魔咒!

幸好在壓測階段發現,等上線後在尖峰時刻爆開,肯定被罵到臭頭!

希望定期重啟維持穩定又不想影響線上服務怎麼辦? 這次的專案受到一些限制,要改成Stateless並非易事,幸好IIS提供另一個選擇 -- 允許管理者自行排定回收Worker Process的時程。剛好系統有每日維護作業時段並對使用者公告,因此在本案例只需將回收作業排在該時段執行就萬事OK。

修改方式如下,透過IIS管理員,找到Appliction Pool,開啟進階設定:

2139-6211-o.gif

如上圖所示,預設Regular Time Interval(minutes)為1740=29小時

2140-dd34-o.gif

將1740改為0,並在Specific Times加上指定的回收時間即可完成設定。
(除了使用IIS管理員,也可修改ApplicationHost.config <recycling>使用PowerShell設定。)

【結論】
如果你的網站會因Worker Process重啟導致使用者狀態遺失,務必調整IIS預設的29小時回收設定,以免在尖峰時間發生悲劇。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK