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

ASP.NET Session 狀態模式完整比較:InProc、StateServer、SQLServer 與自訂供應器

     編輯:關於ASP.NET

Session 狀態模式總覽

web.config 設定:

<system.web>
  <sessionState mode="InProc | StateServer | SQLServer | Custom" 
                timeout="20" 
                cookieless="UseUri | UseCookies | AutoDetect | false"
                regenerateExpiredSessionId="true"
                ...>
  </sessionState>
</system.web>

四大內建模式深度比較

模式儲存位置優點缺點適用場景
InProc (預設)ASP.NET 工作進程記憶體 (w3wp.exe)效能最高 (進程內存取)、無序列化開銷、設定最簡單進程回收/重啟/崩潰 → Session 全失;Web Farm 無法共享;大量資料佔用工作進程記憶體觸發回收單伺服器、中小型應用、非關鍵性 Session 資料
StateServer獨立 Windows 服務 (aspnet_state.exe),預設 TCP 42424進程外隔離,IIS 回收不影響 Session;支援 Web Farm (共享 StateServer);可運行於專用機器網路呼叫延遲 (序列化/反序列化);單點故障 (StateServer 掛掉全站 Session 失效);需手動啟動服務Web Farm、需 Session 持久化、中等流量
SQLServerSQL Server 資料庫 (預設 tempdb 或自訂資料庫)企業級高可用 (叢集/AlwaysOn/鏡像);資料持久化、可查詢稽核;支援大規模 Web Farm效能最低 (DB I/O + 序列化);需授權 SQL Server;資料庫維護備份額外成本任務關鍵、大型 Web Farm、法規要求稽核追蹤
Custom自訂供應器 (Redis、MongoDB、Memcached、Azure Cache)彈性最高、效能可優化、支援分散式架構、現代雲原生首選需自行開發/維護供應器類別;相依第三方基礎設施雲部署、微服務、高併發、需進階功能 (分散式鎖、發布訂閱)

StateServer 設定詳解

<sessionState mode="StateServer" 
              stateConnectionString="tcpip=127.0.0.1:42424" 
              stateNetworkTimeout="30" />
  • stateConnectionString:tcpip=IP:Port,遠端機器需開放防火牆埠。
  • stateNetworkTimeout:網路逾時秒數,預設 30 秒。
  • 服務啟動:services.msc → "ASP.NET State Service" → 啟動類型設為「自動」。
  • 遠端連線需修改登錄:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection = 1 (預設 0 僅本機)。

SQLServer 設定詳解

<sessionState mode="SQLServer" 
              sqlConnectionString="Data Source=127.0.0.1;Initial Catalog=ASPState;User ID=sa;Password=***;Application Name=MyApp" 
              allowCustomSqlDatabase="true" />
  • 安裝腳本:aspnet_regsql.exe -S . -E -ssadd -sstype p (持久化至自訂資料庫 ASPState) 或 -sstype t (tempdb,重啟遺失)。
  • allowCustomSqlDatabase="true" 允許非預設資料庫名稱。
  • 資料表:ASPStateTempSessions、ASPStateTempApplications。

自訂 Session 供應器實作 (以 Redis 為例)

public class RedisSessionStateProvider : SessionStateStoreProviderBase
{
    private ConnectionMultiplexer _redis;
    private IDatabase _db;
    
    public override void Initialize(string name, NameValueCollection config)
    {
        var connStr = config["connectionString"] ?? "localhost:6379";
        _redis = ConnectionMultiplexer.Connect(connStr);
        _db = _redis.GetDatabase();
        base.Initialize(name, config);
    }
    
    public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
    {
        return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
    }
    
    public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
    {
        var key = "session:" + id;
        _db.StringSet(key, "", TimeSpan.FromMinutes(timeout));
    }
    
    public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
    {
        locked = false; lockAge = TimeSpan.Zero; lockId = null; actions = SessionStateActions.None;
        var key = "session:" + id;
        var data = _db.StringGet(key);
        if (data.IsNullOrEmpty) return null;
        // 反序列化 SessionStateItemCollection (略)
        return Deserialize(data);
    }
    
    public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
    {
        var key = "session:" + id;
        var serialized = Serialize(item);
        _db.StringSet(key, serialized, TimeSpan.FromMinutes(item.Timeout));
    }
    
    // 其他必要覆寫:GetItemExclusive, ReleaseItemExclusive, RemoveItem, ResetItemTimeout, Dispose
}

註冊:

<sessionState mode="Custom" customProvider="RedisSessionProvider">
  <providers>
    <add name="RedisSessionProvider" type="MyApp.Providers.RedisSessionStateProvider, MyApp" connectionString="redis:6379" />
  </providers>
</sessionState>

效能與序列化考量

  • InProc:物件直接存放,無序列化,**不可儲存不可序列化物件** (如 DbConnection、Thread、未標記 [Serializable] 的類別) — 但 InProc 不需序列化,故可存放任何物件 (風險:記憶體洩漏、型別安全)。
  • StateServer / SQLServer / Custom:所有物件必須可序列化 (實作 ISerializable 或標記 [Serializable]),預設使用 BinaryFormatter。
  • 大物件警示:Session 存放大型 DataTable、Entity 物件會嚴重拖慢序列化/網路/DB 寫入。建議:只存 ID/Key,實際資料用 Cache/資料庫查詢。

Cookieless Session (無 Cookie 模式)

<sessionState cookieless="UseUri" />

Session ID 嵌入 URL://page.aspx。適用於拒絕 Cookie 的舊裝置,**但有安全風險 (Session ID 暴露於 URL、書籤、Referer、Log)**,現代應用**強烈不建議**使用。

選型決策矩陣

條件推薦模式
單伺服器、開發/測試、低流量InProc
Web Farm (2-10 節點)、需 Session 持久化、無 SQL Server 授權StateServer (建議專用機器 + 監控)
企業級 Web Farm、高可用要求、已有 SQL Server 叢集SQLServer (持久化模式 -sstype p)
雲原生 (Azure/AWS/GCP)、容器化、微服務、高併發Custom (Redis / Azure Cache for Redis / Memcached)
需 Session 資料查詢、稽核、報表SQLServer 或 Custom (支援查詢的存儲)

結語

ASP.NET Session 模式選擇本質是 **效能、可用性、維運成本、架構演進** 的權衡。InProc 最快但最脆弱;StateServer/SQLServer 提供進程外持久化但引入延遲與基礎設施依賴;Custom 供應器 (Redis 為首選) 則是現代分散式系統的標準解法。建議:新專案直接採用 Redis Custom Provider,兼具高效能、高可用、彈性擴展,並避免綁定 IIS/ASP.NET 執行環境。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved