故障現象
- 網站無法打開或極慢,靜態 HTML 正常
重啟 IIS / 回收應用程式集區暫時恢復,過段時間復發
- 系統事件日誌記錄:
ISAPI 'C:\WINDOWS\system32\inetsrv\asp.dll' 報告不健康:
'ASP 不健康,因為 100% 執行請求被掛起,請求佇列使用 0% (或 6%)'
根因分析
- ASP 程式碼缺陷:死迴圈、長時間資料庫查詢、COM 物件未釋放、無限遞迴 → 工作執行緒耗盡。
- 應用程式集區預設回收間隔過長 (1740 分鐘 = 29 小時):記憶體洩漏累積、執行緒池耗盡,最終導致所有執行緒掛起 (Hanging)。
- 多站點共用單一集區:某站點失控拖垮全池其他站點。
解決方案三層次
層次 1:緊急止血 — 調整回收機制
單一站點方案
- 集區屬性 → 「回收工作進程」:
☑ 固定間隔 (分鐘):**300-600** (5-10 小時)
☑ 特定時間:**凌晨 05:00** (低流量時段)
- 代價:回收瞬間 CPU 尖峰、Session 遺失 (若非 InProc 可忽略)。
多站點方案 (核心建議)
- 依流量/重要性建立**多個應用程式集區**
- 每集區配置 10 個站點左右 (視流量調整)
- 高流量/關鍵站點**獨享一個集區**
- 每集區回收間隔 **300 分鐘**,錯峰設定回收時間 (如 02:00, 03:00, 04:00...)
記憶體估算: 每集區 ~120 MB 基礎佔用,8GB 記憶體可跑 50+ 集區。
分配操作: 網站屬性 → 「主目錄」→「應用程式集區」下拉選單選擇目標集區。
層次 2:針對性隔離 — 知名問題站點 (如動網論壇) 專屬集區
- 建立專屬集區 (如
DvBBS_Pool)
- 將論壇虛擬目錄指派給此集區
- 集區屬性 → 回收設定:
☑ 固定間隔 (如 180 分鐘)
☑ 特定時間:**凌晨 03:00**
- 進階:設定集區身分為專用低權限帳號 (而非 Network Service),限制損害範圍。
原理: Access 驅動程式在 IIS 6.0 多執行緒下已知相容性問題,隔離可防止拖垮主站。
層次 3:根治 — 程式碼層面修復 + 自動化運維
- 檢查 ASP 程式碼:
✅ 關閉 Recordset/Connection 物件 (Set obj = Nothing)
✅ 避免大量資料一次性輸出 (分頁)
✅ 索引優化慢查詢
✅ 移除 Server.CreateObject 迴圈內重複建立
- 部署自動回收腳本 (排程任務每日執行):
cscript //nologo iisapp.vbs /a | find "W3WP.exe" > pools.txt
for /f "tokens=2" %%i in (pools.txt) do cscript iiscnfg.vbs /stop %%i /start %%i
- 善用 IIS 備份/還原 (metabase 備份)、虛擬主機 IP 批次修改腳本、存取日誌分析自動化。
預防性監控指標
| 指標 | 警戒閾值 | 動作 |
| 應用程式集區私有記憶體 | > 500 MB (視機型) | 排程回收 / 調查洩漏 |
| ASP 請求佇列長度 | > 100 | 擴充執行緒 / 隔離站點 |
| W3WP.exe CPU 持續 > 80% | 5 分鐘 | 分析堆疊 / 回收集區 |
| ASP 錯誤率 | > 1% | 程式碼審查 |
結語
IIS 6.0 假死 90% 源於「集區過大 + 回收過慢 + 程式碼洩漏」。拆分集區 + 縮短回收 + 錯峰排程 是零成本、立竿見影的治本之策。長期仍需投入程式碼品質與自動化運維,才能實現真正的高可用。