同事報案,某台 ASP.NET 網站有幾個網頁會隨機性冒出錯誤,共同特徵都是 Session 物件遺失造成。

在事件檢視器出現大量 Event 5074 WAS 訊息,時間點與出錯時間吻合,初步推斷 AppPool 被回收導致 Session 物件遺失是隨機出錯原因:

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' 的工作者處理序已要求回收。

我對這個訊息並不陌生,之前在調查 IIS 29 小時魔咒時有交手過。查看問題 IIS 設定的回收時間是預設值 1740 分鐘(29小時),幾分鐘出現一次 Event 5074 明顯不合理。

試著改用另外新建的 AppPool,網站隨機出錯的狀況消失,看起來是 AppPool 設定有問題。肉眼比對新舊 AppPool 設定沒看出明顯不同,但我留意到另一件事,工作管理員中有兩個舊 AppPool 的 w3wp.exe Process!

用此一線索爬文,我學到一些新東西 - 這種 AppPool 跑一個以上 Worker Process 的做法稱為 Web Garden。

Web Garden 允許多個 Worker Process 分擔 Request 流量,能充分利用閒置 CPU 資源。接著再查到蔡煥麟老師的文章:謹慎使用 Web Garden, 裡面提到使用 Web Garden 模型可能遇到 Session 遺失的狀況。在 Web Garden 模式下,進入應用程式的第一個 Request 和後續的 Request 可能被分配給不同的 Worker Process,若 Session 是保存在記憶體裡(In-Process Session),就可能出現找不到 Session 的狀況, 猜想這才是隨機出現 Session 物件相關錯誤的真正原因。(註:同樣問題在 WebFarm 也會發生)

回頭檢查問題 AppPool 的 Worker Process 設定,Bingo!

工作者處理序數上限被誤設成一個不合理數字 - 4096。一般來說,Worker Process 數量上限應小於 CPU 核心數,搾乾效能的極致是讓每個 Worker Process 吃光一整顆 CPU 核心,之後再增加 Process 也不會更快。 頻繁的 Event 5074 事件也許與這個極端設定值有關,不過這個設定脫離常軌,就不多花時間研究了。

由於網站有使用 In-Process Session 而平日 CPU 使用率游刃有餘,將 Worker Process 數上限改回 1,結束這回合。

A case of ASP.NET session is randomly null in multiple IIS worker process environment.


Comments

# by Huang

建議先發現該集區的工作者處理序中有多個Request花費時間過久消化不良的情形時再增加。如果增加了就改成StateServer模式才不會掉session

Post a comment