日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

asp.net mvc4开启SqlServer 会话共享模式

發布時間:2023/12/10 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 asp.net mvc4开启SqlServer 会话共享模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

應用部署結構(精簡):

站點部署在Nginx后面,以Nginx作為反向代理,不希望在Nginx上設置ip_hash,實現比較真實的負載均衡效果。

這時考慮到需要讓site1和site2同時共享會話信息,進行如下的配置:

默認情況下asp.net站點的會話模式是采用Inproc模式,這種模式在站點因IIS重啟會導致丟失用戶會話(已經登陸的用戶會自動重定向到登陸頁面),在本次實踐中使用SqlServer模式

創建會話數據庫(獨立于應用):

aspnet_regsql.exe -S server_ip -E -ssadd -sstype c -d dbname

更多參數可以參考命令的幫助aspnet_regsql.exe /?,通常路徑在**C:\Windows\Microsoft.NET\Framework64\{.net_version}**下

配置如下:

<sessionState mode="SQLServer" sqlConnectionString="server=server_ip;database=dbname;uid=user;pwd=pwd;" allowCustomSqlDatabase="True" cookieless="false" timeout="20" />

會話數據庫的表ASPStateTempApplications中存放應用的信息(appId和AppName),每一個站點一條記錄,我兩個站點分別使用該數據庫所以有兩條記錄,如圖:

通過以上的配置, 貌似完成了會話的共享,這時候通過Nginx的IP地址發送兩個請求到服務器(一個登陸,一個獲取用戶考試列表)。通過Nginx的日志發現兩次請求被分發到兩臺不同的后端服務器:

從圖中可以看出第一次請求是192.168.2.2:80803這個站點處理,第二個請求被192.168.2.5:8083這個站點處理。明明已經設置了會話共享為什么第二次請求被提示為未登錄。檢查是否登陸的代碼如下:

public class WebApiCheckLoginFilterAttribute : ActionFilterAttribute{public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext){LoginService service = new LoginService();string controllerName = actionContext.ActionDescriptor.ControllerDescriptor.ControllerName;string actionName = actionContext.ActionDescriptor.ActionName;bool isAuthAction = controllerName.Equals("ExamAPI") && actionName.Equals("Login");if (!isAuthAction){HttpSessionState Session = System.Web.HttpContext.Current.Session;if (Session["user"] == null){throw new HttpException((int)HttpStatusCode.NonAuthoritativeInformation, "未登錄用戶或已在其他設備中登錄");}if (!service.IsOnline(Model.DeviceType.Phone, Session.SessionID)){throw new HttpException((int)HttpStatusCode.NonAuthoritativeInformation, "未登錄用戶或已在其他設備中登錄");}}base.OnActionExecuting(actionContext);}}

上述代碼是為了檢查如果session['user']==null,就會提示是未登陸。已經配置了會話共享為什么session['user']還是獲取不到用戶對象?通過各種嘗試發現asp.net在處理session的時候會根據站點的AppId加上瀏覽器上的SessionId在數據庫表([ASPStateTempSessions])中創建會話記錄,SessionId的值如下:

0kf0zoq4to3h0z0b1eztw43s28d8c075
  • 28d8c075 是AppId685293685的16進制(對應的AppId)
  • 0kf0zoq4to3h0z0b1eztw43s是客戶端cookie中存放的sessionid

通過查看存儲過程[dbo].[TempGetAppID]的代碼,發現asp.net會通過每個站點的AppName(見表ASPStateTempApplications)去獲取AppId,然后將SessionId+AppId(16進制)作為主鍵插入到表ASPStateTempSessions中,這樣的處理邏輯是保證一個會話數據庫會被N個站點共同使用,不用每個站點創建自己的會話數據庫。隱藏的問題是如果站點的AppName不一樣會導致獲取的AppId不一樣達不到會話共享的目的。

驗證過程如下:向Nginx發送兩個請求(一個登陸,一個獲取考試列表)會在ASPStateTempSessions表中產生兩條記錄,正常情況應該兩個請求也應該只產生一條會話記錄。

為了保證只產生一條會話記錄可以通過讓site1和site2的AppName保持一致,每次通過存儲過程[dbo].[TempGetAppID]獲取的AppId都是同一個。 修改方式為:

修改完成后,再次發送兩個請求(一個登陸,一個獲取考試列表),兩個請求經過Nginx分發到兩個站點后在ASPStateTempSessions只產生一條會話記錄,這樣才真正的實現會話的一致性。

配置machineKey,在做asp.net站點集群的時候如果站點中使用到cookie或viewstate的話需要配置machineKey來確保多臺機器共享驗證和ViewState.每個節點上的machineKey配置必須一致

按照MSDN的標準說法:“對密鑰進行配置,以便將其用于對 Forms 身份驗證 Cookie 數據和視圖狀態數據進行加密和解密,并將其用于對進程外會話狀態標識進行驗證.加密和解密使用的就是machineKey

生成machineKey的代碼

public static string CreateMachineKey(int length){byte[] random = new byte[length / 2];RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();rng.GetBytes(random);StringBuilder builder = new StringBuilder();for (int i = 0; i < random.Length; i++){builder.Append(string.Format("{0:X2}", random[i]));}return builder.ToString();}string decryptionKey= CreateMachineKey(48);string validationKey = CreateMachineKey(128);

web.config配置內容

<system.web><compilation targetFramework="4.0" /><machineKey validationKey="validationKey" decryptionKey="decryptionKey"/> ...other...</system.web>

小結

asp.net 站點的會話模式如果選用SqlServer的話,需要保證站點群(可能有N個站點)通過[dbo].[TempGetAppID]存儲過程獲取AppId后的結果是相同的。可以通過修改存儲過程,也可以通過修改AppName。

轉載于:https://my.oschina.net/hulingfeng/blog/1525737

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的asp.net mvc4开启SqlServer 会话共享模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。