現象:Windows Server 2003 虛擬主機環境,網站間歇性回傳 HTTP 503 Service Unavailable,重整幾次又正常。根因:**應用程式池預設限制 (佇列長度、記憶體、CPU、閒置超時、快速失敗保護) 在共享主機高密度部署下極易觸發**。本文提供標準調優參數與排查邏輯。
錯誤機制解析
- IIS 6.0 引入應用程式池隔離,每池對應一個工作進程 (w3wp.exe)
- 預設限制:佇列長度 1000、私有記憶體限制 0 (無限制)、虛擬記憶體限制 0、閒置超時 20 分鐘、定期回收 1740 分鐘 (29 小時)、快速失敗保護 (5 分鐘內 5 次失敗即停用池)
- 共享主機數百站點共用單機資源,極易觸發記憶體/CPU/佇列/快速失敗門檻
標準調優參數 (IIS 管理員 → 應用程式池 → 內容)
| 頁籤 | 設定項 | 建議值 | 說明 |
| 回收工作進程 | 固定間隔 (分鐘) | 15-60 | 避開預設 1740 分鐘 (29小時) 導致記憶體洩漏累積;視應用穩定性設 30-60 分鐘 |
| 記憶體回收 - 虛擬記憶體 | 勾選,設 800-1500 MB | 防止單一池佔盡系統虛擬記憶體導致其他池/系統服務餓死 |
| 記憶體回收 - 私有記憶體 | 勾選,設 300-800 MB | 防止記憶體洩漏應用無限增長,強制回收釋放 |
| 效能 | 啟用快速失敗保護 | 取消勾選 | 共享主機極易誤觸發 (5 分鐘 5 次 500 錯誤即停池);關閉後依賴記憶體/佇列/健康檢查保護 |
| 效能 | 佇列長度 | 2000-5000 | 緩衝突發流量,避免 503 直接拒絕 |
| 效能 | 限制核心數 (SMP) | 視授權核心數設定 | 防止單池佔用所有 CPU 核心 |
| 健康狀態 | 啟用 Ping 檢查 | 勾選,間隔 30 秒 | 偵測掛起進程,自動終結重啟 |
| 健康狀態 | 啟用快速失敗保護 | 同上,建議關閉 | — |
| 身分識別 | 應用程式池身分識別 | NetworkService / 自訂低權限帳號 | 最小權限原則,避免 LocalSystem |
資料庫型站點登入狀態丟失 (Session 丟失) 同步解決
現象: 使用者登入幾分鐘自動登出,需重新登入。
根因: 應用程式池回收導致 InProc Session 清空。
方案 (Web.config):
<system.web>
<sessionState mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
cookieless="false" timeout="30" />
<!-- 或 SQLServer 模式:需建立 ASPState 資料庫 -->
</system.web>
- 確認 ASP.NET State Service 已啟動 (`services.msc` → `aspnet_state` → 自動/啟動)
- 防火牆開放 42424 埠 (僅本機/內網)
- 機器金鑰 (``) 多伺服器場需同步
進階排查:若調優後仍頻繁 503
- 檢查系統事件日誌 (System/Application): 事件 ID 1000/1001/1002 (應用程式錯誤/掛起/回收原因)
- 啟用 IIS 進程追蹤 (Failed Request Tracing / FREB): 捕捉 503 完整堆疊、模組、處理階段
- 監控 w3wp.exe 記憶體/CPU/控制代碼/執行緒: Process Explorer / PerfMon / DebugDiag 分析洩漏/死鎖/高 CPU
- 檢查應用程式碼: 靜態集合未清理、大物件堆積 (LOH)、同步鎖爭用、資料庫連線未釋放、大量反射/序列化
- 資源配額: 確認主機商未對應用程式池設定極嚴格的 CPU/記憶體/頻寬/IIS 連線數配額
- 升級方案: 若業務關鍵,強烈建議遷移至 VPS/雲主機/容器,擁有專屬資源與完整 IIS 控制權
避坑提醒
- ❌ 盲目增大佇列長度不解決根因 → 只是延遲 503 爆發,積壓請求更耗記憶體
- ❌ 關閉快速失敗保護後不加健康檢查 → 掛起進程長期佔用資源
- ✅ 記憶體回收門檻 + 固定間隔回收 + 健康檢查 Ping 三位一體
- ✅ Session 外部化 (StateServer/SQLServer/Redis) 解耦進程生命週期
- ✅ 建立應用程式池效能基線 (正常記憶體/CPU/佇列/回收頻率),異常即告警
「Service Unavailable」不是錯誤,是**資源保護機制觸發的信號**。聽懂信號、調對參數、解耦狀態、建基線,共享主機也能跑出穩定可用的服務等級。