首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Session 遺失原因分析與完整解決方案

     編輯:ASP.NET 基礎

前言

Session 遺失是 ASP.NET 開發常見痛點。本文深入剖析 InProc 模式下 Session 遺失的根本原因,並提供三種儲存模式的完整設定指南與避坑清單。

核心原因:InProc 模式的進程回收

預設 mode="InProc" 將 Session 存於 ASP.NET 工作進程 (IIS 5: aspnet_wp.exe; IIS 6+: w3wp.exe) 記憶體中。以下事件會觸發進程回收,導致 Session 全部遺失:

  1. web.config 或 Global.asax 異動
  2. /bin 目錄下組件 (.dll/.pdb) 更新
  3. 應用程式集區達到記憶體限制 (memoryLimit)
  4. 防毒軟體掃描 .config 檔案觸發檔案系統通知
  5. 應用程式集區定期回收 (預設 1740 分鐘)
  6. IIS 重啟 / 伺服器重開機

三種 Session 儲存模式完整比較

模式儲存位置優點缺點適用場景
InProc工作進程記憶體效能最快、設定最簡單進程回收遺失、無法跨伺服器、記憶體壓力大單機、低流量、開發測試
StateServer獨立 Windows 服務 (aspnet_state.exe)進程回收不影響、支援 Web Farm、可跨機器序列化開銷、需啟動服務、單點故障中型 Web Farm、不想架 SQL
SQLServerSQL Server 資料庫持久化、支援叢集/高可用、可跨資料中心延遲最高、需授權、維護成本高大型企業、高可用需求、跨資料中心
Custom (Redis 等)分散式快取高效能、高可用、支援多種資料結構需額外基建、程式碼複雜度較高現代雲原生、微服務、高併發

StateServer 設定步驟

1. 啟動 ASP.NET State Service

sc config aspnet_state start= auto
net start aspnet_state

或透過「服務」MMC (services.msc) 將 ASP.NET State Service 設為自動並啟動。

2. 修改 web.config

<sessionState 
    mode="StateServer"
    stateConnectionString="tcpip=127.0.0.1:42424"
    cookieless="false"
    timeout="30" />

3. 跨機器部署

將 stateConnectionString 指向專用 State Server:

stateConnectionString="tcpip=192.168.1.100:42424"

注意:所有 Web 伺服器的 machineKey 必須一致,否則無法解密 Session ID。

SQLServer 設定步驟

1. 建立 Session 資料庫

aspnet_regsql -S . -E -ssadd -sstype p

產生 ASPState 資料庫與 ASPStateTempApplications、ASPStateTempSessions 資料表。

2. 修改 web.config

<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; }
}

常見誤區與避坑指南

1. cookieless="true" 的陷阱

會將 Session ID 嵌入 URL (/sessionId/page.aspx),導致:

  • SEO 災難 (重複內容)
  • 分享連結洩露 Session
  • 行動裝置相容性差

建議:永遠使用 cookieless="false" (預設) 或 。

2. Web Farm 未同步 machineKey

<machineKey validationKey="AutoGenerate,IsolateApps" 
            decryptionKey="AutoGenerate,IsolateApps" 
            validation="SHA1" decryption="AES" />

所有節點必須使用 相同 的 validationKey/decryptionKey。

3. Session 鎖定導致併發阻塞

ASP.NET 預設對同一 Session 的請求會序列化執行。長時間 AJAX 輪詢會封鎖其他請求。

解法:

  • ASP.NET Core: services.AddSession(o => o.IdleTimeout = ...) 無鎖定問題。
  • ASP.NET 4.x: 於 Page 指示詞加 EnableSessionState="ReadOnly" (唯讀) 或 (停用)。

4. Application Pool Identity 權限不足 (StateServer/SQL)

確認應用程式集區身分 (NetworkService / 自訂帳號) 有權連線 State Server (TCP 42424) 或 SQL Server。

診斷工具與技巧

  1. Event Viewer:查看 Application 事件記錄,搜尋 aspnet_wp.exe / w3wp.exe 回收原因。
  2. Failed Request Tracing (FREB):啟用追蹤 MODULE_SET_RESPONSE_ERROR_STATUS 觀察 Session 模組行為。
  3. 自訂 Session 追蹤模組:在 Session_Start/Session_End 寫入 Log (Serilog/NLog),記錄 SessionId、UserAgent、建立/結束時間。

現代替代方案

  • ASP.NET Core:內建 IDistributedCache,支援 Redis、SQL Server、NCache,無 Session 鎖定問題。
  • JWT / Stateless Auth:將使用者狀態編碼在 Token,完全無 Session 伺服器端儲存。
  • SignalR + Redis Backplane:即時應用共享連線狀態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved