Session 遺失是 ASP.NET 開發常見痛點。本文深入剖析 InProc 模式下 Session 遺失的根本原因,並提供三種儲存模式的完整設定指南與避坑清單。
預設 mode="InProc" 將 Session 存於 ASP.NET 工作進程 (IIS 5: aspnet_wp.exe; IIS 6+: w3wp.exe) 記憶體中。以下事件會觸發進程回收,導致 Session 全部遺失:
web.config 或 Global.asax 異動/bin 目錄下組件 (.dll/.pdb) 更新memoryLimit)| 模式 | 儲存位置 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| InProc | 工作進程記憶體 | 效能最快、設定最簡單 | 進程回收遺失、無法跨伺服器、記憶體壓力大 | 單機、低流量、開發測試 |
| StateServer | 獨立 Windows 服務 (aspnet_state.exe) | 進程回收不影響、支援 Web Farm、可跨機器 | 序列化開銷、需啟動服務、單點故障 | 中型 Web Farm、不想架 SQL |
| SQLServer | SQL Server 資料庫 | 持久化、支援叢集/高可用、可跨資料中心 | 延遲最高、需授權、維護成本高 | 大型企業、高可用需求、跨資料中心 |
| Custom (Redis 等) | 分散式快取 | 高效能、高可用、支援多種資料結構 | 需額外基建、程式碼複雜度較高 | 現代雲原生、微服務、高併發 |
sc config aspnet_state start= auto
net start aspnet_state
或透過「服務」MMC (services.msc) 將 ASP.NET State Service 設為自動並啟動。
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
cookieless="false"
timeout="30" />
將 stateConnectionString 指向專用 State Server:
stateConnectionString="tcpip=192.168.1.100:42424"
注意:所有 Web 伺服器的 machineKey 必須一致,否則無法解密 Session ID。
aspnet_regsql -S . -E -ssadd -sstype p
產生 ASPState 資料庫與 ASPStateTempApplications、ASPStateTempSessions 資料表。
<sessionState
mode="SQLServer"
sqlConnectionString="Data Source=192.168.1.50;Initial Catalog=ASPState;User ID=sa;Password=***;"
cookieless="false"
timeout="30" />
使用 StateServer / SQLServer / Custom 模式時,存入 Session 的自訂類別 必須標記 [Serializable]:
[Serializable]
public class UserProfile
{
public int UserId { get; set; }
public string Name { get; set; }
public List Roles { get; set; }
}
會將 Session ID 嵌入 URL (/sessionId/page.aspx),導致:
建議:永遠使用 cookieless="false" (預設) 或 。
<machineKey validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"
validation="SHA1" decryption="AES" />
所有節點必須使用 相同 的 validationKey/decryptionKey。
ASP.NET 預設對同一 Session 的請求會序列化執行。長時間 AJAX 輪詢會封鎖其他請求。
解法:
services.AddSession(o => o.IdleTimeout = ...) 無鎖定問題。Page 指示詞加 EnableSessionState="ReadOnly" (唯讀) 或 (停用)。確認應用程式集區身分 (NetworkService / 自訂帳號) 有權連線 State Server (TCP 42424) 或 SQL Server。
aspnet_wp.exe / w3wp.exe 回收原因。MODULE_SET_RESPONSE_ERROR_STATUS 觀察 Session 模組行為。Session_Start/Session_End 寫入 Log (Serilog/NLog),記錄 SessionId、UserAgent、建立/結束時間。IDistributedCache,支援 Redis、SQL Server、NCache,無 Session 鎖定問題。