如何解決asp.net負(fù)載均衡時Session共享的問題
每個客戶端在訪問網(wǎng)站時,都會創(chuàng)建相應(yīng)的Session,用來保存客戶的狀態(tài)信息,網(wǎng)站如果做了負(fù)載均衡,session共享是要做的,IIS對于session的存儲有五種模式
一、ASP.Net session存儲方式
1、InProc模式(進(jìn)程內(nèi)模式) 。為默認(rèn)設(shè)置。
會話狀態(tài)存儲在Web服務(wù)器上的內(nèi)存中。
2、StateServer模式(狀態(tài)服務(wù)器模式)。
會話狀態(tài)存儲在一個名為ASP.Net狀態(tài)服務(wù)的單獨進(jìn)程中。這確保了在重新啟動Web應(yīng)用程序時會保留會話狀態(tài),并讓會話狀態(tài)可用于網(wǎng)路場中的多個Web服務(wù)器。
3、SQL Server模式。
會話狀態(tài)存儲到一個SQL Server數(shù)據(jù)庫中。這確保了在重新啟動Web應(yīng)用程序時會保留會話狀態(tài),并讓會話狀態(tài)可用于網(wǎng)路場中的多個Web服務(wù)器。
4、Custom模式
此模式允許您指定自定義存儲提供程序。
5、Off模式
此模式禁止會話狀態(tài)。
二、使用StateServer存儲session
如果網(wǎng)站做了負(fù)載均衡,對于session存儲就只能選擇2、3、4了,下面先來介紹一下StateServer模式,首先得開啟狀態(tài)服務(wù)
然后再對web站點的“會話狀態(tài)”進(jìn)行設(shè)置
啟用本機(jī)的狀態(tài)服務(wù)
會自動在web.config里生成配置文件(如果不能生成就手動添加)
<sessionStatemode=”StateServer”stateConnectionString=”tcpip=loopback:42424″timeout=”20″/>
但是這里就存在一個問題,如果每臺服務(wù)器都照上面配置,各服務(wù)器的Session都存儲在本機(jī)的StateServer里面,還是沒有啟動共享的作用,這里就需要讓一臺StateServer共享出來讓其他服務(wù)器訪問,并將Session存儲到上面,運行regedit → 打開注冊表 → 找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters節(jié)點 → 將 AllowRemoteConnection 的鍵值設(shè)置成“1”(1 為允許遠(yuǎn)程電腦的連接,0 代表禁止)
也可以修改StateServer的端口
接下來將其它服務(wù)器中web.config的配置文件進(jìn)行修改(sessionState指向開啟了允許遠(yuǎn)程訪問的StateServer)
<sessionStatemode=”StateServer”stateConnectionString=”tcpip=10.16.5.30:22222″timeout=”20″/>
用StateServer這種共享式的session存儲方式不僅有安全隱患,而且像上面那臺共享的StateServer只要重啟服務(wù)器,所有的session都會丟失,所以這種session存儲方式不是很完美,用StateServer存儲sesssion比較適合單機(jī)IIS開啟多進(jìn)程的。
三、使用SQL server存儲session
要做保證安全并且不會因為重啟服務(wù)器導(dǎo)致session丟失,那就要用sql server來存儲session,ASP.NET 2.0版本后微軟提供了aspnet_regsql.exe工具可以方便的配置Session數(shù)據(jù)庫.該工具位于 Web 服務(wù)器上的系統(tǒng)根目錄Microsoft.NETFramework版本號文件夾中
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
aspnet_regsql.exe -ssadd -sstype c -d <Database Name> -S <SQL Server IP> -U <User Name> -P <Password>
aspnet_regsql.exe -ssadd -sstype c -d ASPState -S 10.16.5.36 -U sa -P HAha789
注:<Database Name>為數(shù)據(jù)庫名為ASPState ,<SQL Server IP>為數(shù)據(jù)庫實例名像 IBM-PC\SQLEXPRESS (若數(shù)據(jù)庫不是2005的不要寫ip地址,否則會連接失?。?,<User Name>為sa(或與sa同等權(quán)限的),<Password> 為 sa用戶名的密碼會話定義成功,但是會提示在web應(yīng)用中進(jìn)行相應(yīng)的配置,此時查看SQLServer會發(fā)現(xiàn)增加了數(shù)據(jù)庫ASPState,但是沒有表。
在命令行下運行如下命令:aspnet_regsql.exe -ssadd -sstype p -S <SQL Server IP> -U <User Name> -P <Password>
aspnet_regsql.exe-ssadd-sstypep-S10.16.5.36-Usa-PHAha789
該命令對此應(yīng)用進(jìn)行了持久化操作。這時會看到ASPState數(shù)據(jù)庫里面多了兩張表,ASPStateTempSession就可以用來保存Session,接下來要對web站點的“會話狀態(tài)”進(jìn)行設(shè)置
ASPStateTempSessions 表中的SessionID ,包括兩個部分:網(wǎng)站生成的24位SessionID及8位AppId組成,對于不同的站點,其AppId和AppName也不同,在能夠在不同站點下Session共享,就得保證這個32位的SessionID 一致,所以可以通過修改存儲過程TempGetAppID,使其得到的SessionID與AppName無關(guān),修改TempGetAppID如下
修改web.config(在數(shù)據(jù)庫中為ASPState單獨分配一個帳戶)
<sessionStatemode="SQLServer"sqlConnectionString="datasource=10.16.5.36;userid=sa;password=HAha789"cookieless="false"timeout="20"></sessionState>
這樣就實現(xiàn)了sql server對session的存儲,當(dāng)然也可以用memcache來存儲session
四、ASP.NET錯誤,驗證視圖狀態(tài)MAC失敗
但在在網(wǎng)站登錄訪問時卻報錯了“ASP.NET錯誤,驗證視圖狀態(tài)MAC失敗”,baidu了一下,大部分人都說是在頁里或web.config里加EnableEventValidation="false" EnableViewStateMac="false" ViewStateEncryptionMode="Never" 這些屬性的設(shè)置。但是這并不從根本上解決問題,相反這樣做了反而更加不安全。不能說出錯就不用了?出錯得解決問題,得從根本上解決問題。
分析錯誤原因:
ASP.NET 中有很多涉及到加密的東西,比如 ViewState,比如 FormsAuthenticationTicket,這些東西都是要傳送到客戶端的,加密才能保障其安全性。加密就得有個私鑰,但這個私鑰我們并沒有指定啊,那是因為 ASP.NET 自動生成的。但是如果是在網(wǎng)絡(luò)場或群集中,或者在某些做了 CDN 加載的虛擬主機(jī)中,由于涉及到多臺服務(wù)器 ASP.NET 就無法為各臺機(jī)器自動生成相同的私鑰,這就造成了這個服務(wù)器產(chǎn)生的數(shù)據(jù),那臺服務(wù)器解析不出來。于是就出錯了。怎么辦?既然 ASP.NET 在多臺服務(wù)器上無法自動隨機(jī)生成相同的私鑰,那只有我們自己指定了。
MachineKey生成工具,自動生成代碼
https://www.fishlee.net/tools/machinekeygenerator
將生成的Machinekey插入到web.config中:
<view class="list" wx:for="{{list}}" wx:key> <view class="item"> <view class="wrap">{{item}}</view> <view class="delete"><text>刪除</text></view> </view> </view>
MachineKey的作用:
ASP.net 使用 forms authentication 時的 cookie 數(shù)據(jù)的加密和解密。以確保這部分?jǐn)?shù)據(jù)不會被篡改viewstate 數(shù)據(jù)的加密和解密。以確保這部分?jǐn)?shù)據(jù)不會被篡改。使用進(jìn)程外session(out-of-process session)時,對會話狀態(tài)標(biāo)識進(jìn)行驗證。利用SessionStateMode的SQLServer來實現(xiàn)session共享,畢竟是微軟的東西,具有一定的局限行,只能是sql server。其實session共享可以用其他的數(shù)據(jù)庫,比如memcache、redis
五、ASP.NET 狀態(tài)數(shù)據(jù)庫FAQ
1、如果把SESSION值存放到數(shù)據(jù)庫中去,用戶關(guān)閉了程序那怎么樣清空數(shù)據(jù)庫里的SESSION值呢?
實際ASP.NET在創(chuàng)建狀態(tài)數(shù)據(jù)庫的時候會在SQL Server代理(SQL Server Agent)的作業(yè)中添加一個作業(yè),名稱為<狀態(tài)數(shù)據(jù)庫名>_Job_DeleteExpiredSessions。如果打開SQL Server代理服務(wù)數(shù)據(jù)庫可以通過添加的狀態(tài)記錄的超時時間字段(Exprires)定期對超時的狀態(tài)數(shù)據(jù)進(jìn)行刪除。
2、ASPStateTempSessions表中的SessionId字段如何使用?
數(shù)據(jù)庫中此表的SessionID字段的值,由SessionID和AppID共同組成,最后8位為AppID所以,后8位之前一定是SessionID。例如,存儲在數(shù)據(jù)庫中的值為"ekr30c3mwvnc3145yrswew3a037e5e5a",后8位的"037e5e5a"為AppID,而前面的"ekr30c3mwvnc3145yrswew3a"為應(yīng)用程序中你可以使用Session.SessionID獲得的字符串。
3、如何判斷Session何時被更新的?
Session記錄被更新時會同時更新Expires和LockDateLocal,Expires字段為UTC時間,如果想通過本地之間進(jìn)行比較判斷還是需要使用LockDateLocal。
4、獲得Web.config配置文件節(jié)點信息的程序?
''獲得Web.config文件配置實例
Dim configuration As System.Configuration.Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/web.config")
''獲得狀態(tài)配置節(jié)點實例
Dim mSessionStateSection As System.Web.Configuration.SessionStateSection = CType(configuration.GetSection("system.web/sessionState"),System.Web.Configuration.SessionStateSection)
''獲得狀態(tài)模式
Response.Write(mSessionStateSection.Mode)
''獲得狀態(tài)超時時間
Response.Write(mSessionStateSection.Timeout)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 如何在ASP.NET Core中使用Session的示例代碼
- Asp.Net Core中基于Session的身份驗證的實現(xiàn)
- 淺談ASP.NET Core中間件實現(xiàn)分布式 Session
- 解析Asp.net Core中使用Session的方法
- asp.net(C#)清除全部Session與單個Session的方法
- 詳解ASP.NET中Session的用法
- ASP.NET ASHX中獲得Session的方法
- ASP.NET將Session保存到數(shù)據(jù)庫中的方法
- asp.net session的使用與過期實例代碼
- Asp.net中判斷一個session是否合法的方法
- ASP.NET MVC在基控制器中處理Session
相關(guān)文章
asp.net 日期函數(shù) 某月的第一天和最后一天的日期
常用asp.net日期操作函數(shù)-得到某月的第一天和最后一天的日期2008-12-12在.NET中掃描局域網(wǎng)服務(wù)的實現(xiàn)方法
下面小編就為大家分享一篇在.NET中掃描局域網(wǎng)服務(wù)的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01.NET?core項目AsyncLocal在鏈路追蹤中的應(yīng)用
這篇文章主要為大家介紹了.NET?core項目zhong?AsyncLocal在鏈路追蹤中的應(yīng)用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05