详解Session分布式共享(.NET CORE版)
一、前言&回顧
?????? 在上篇文章Session分布式共享 = Session + Redis + Nginx中,好多同學(xué)留言問(wèn)了我好多問(wèn)題,其中印象深刻的有:nginx掛了怎么辦?采用Redis的Session方案與微軟Session方案相比,有什么優(yōu)勢(shì)呢?Cookie也可以取代Session的,采用Redis的Session方案優(yōu)勢(shì)在哪里?Nginx的iphash方式到底是什么?MachineKey有啥用?Net Core怎樣實(shí)現(xiàn)?
?????? 那會(huì)兒看到大家的提問(wèn),我的回答也只是從應(yīng)用層面回答,基本上的回答可以總結(jié)為:“別人這么做了,解決了這個(gè)問(wèn)題,我用這個(gè)方法也解決了這個(gè)問(wèn)題,原理請(qǐng)看鏈接。”很慚愧的說(shuō),那時(shí)的我并沒(méi)有完全理解他真正的優(yōu)勢(shì)在哪里,只是憑著直覺(jué)和經(jīng)驗(yàn)知道這樣做比較好,知道當(dāng)一部分東西不可控時(shí)候,將其解耦、可視化、集群就可以讓一個(gè)系統(tǒng)更加健壯,但沒(méi)有一個(gè)理論支撐。經(jīng)過(guò)最近一段時(shí)間的查閱資料和閱讀書籍,對(duì)此有了深刻理解,本文將從網(wǎng)站架構(gòu)的可用性角度對(duì)這種Session共享進(jìn)行分析和講解,并用.net core再次實(shí)現(xiàn)這種架構(gòu)模式。(Session分布式共享的net core版,因?yàn)楣ぷ鳑](méi)有機(jī)會(huì)應(yīng)用到生產(chǎn)環(huán)境,過(guò)往經(jīng)驗(yàn)就更別提了,所以只是研究性的,請(qǐng)大家注意,但園子里早有大牛寫出了相關(guān)文章,本文結(jié)束會(huì)將相關(guān)文章貼出)
二、網(wǎng)站可用性--Session管理
?????可用性是網(wǎng)站架構(gòu)中非常重要的一環(huán),什么是可用性,說(shuō)的簡(jiǎn)單些,就是用戶隨時(shí)隨地打開(kāi)這個(gè)網(wǎng)站,這個(gè)網(wǎng)站都能打開(kāi),并且里面的功能都能用。如果可用性不高會(huì)出現(xiàn)什么情況?大家想象一下春節(jié)在12306搶票的情景,網(wǎng)站各種崩潰,大家保準(zhǔn)會(huì)想:要是有別的方式能買到票,我才不用12306這個(gè)破網(wǎng)站呢。這個(gè)例子有點(diǎn)極端,因?yàn)闃I(yè)務(wù)場(chǎng)景比較極端,當(dāng)然,這種現(xiàn)象也不光是網(wǎng)站可用性這一環(huán)出了問(wèn)題。但是一個(gè)網(wǎng)站三天兩頭打不開(kāi),要么是點(diǎn)開(kāi)了里面的頁(yè)面到處是報(bào)錯(cuò)頁(yè)面和操作無(wú)反應(yīng),你還會(huì)用這個(gè)網(wǎng)站么?我相信我們?cè)跒g覽網(wǎng)站時(shí)候,只要不像12306這種壟斷業(yè)務(wù)的網(wǎng)站,出現(xiàn)不可用的情況,我們一定會(huì)離開(kāi)尋找其他類似的網(wǎng)站。
?????Session管理是網(wǎng)站可用性的內(nèi)容之一,大家都知道Http是無(wú)狀態(tài)請(qǐng)求,即無(wú)法追蹤上次Http請(qǐng)求的相關(guān)信息,但是業(yè)務(wù)中大量需要將Http變?yōu)橛袪顟B(tài)請(qǐng)求,Session就隨之產(chǎn)生了,可是在分布式網(wǎng)站設(shè)計(jì)中,無(wú)狀態(tài)請(qǐng)求才能實(shí)現(xiàn)網(wǎng)站的橫向拓展(增減應(yīng)用服務(wù)器),因此又與Session相矛盾,因?yàn)镾ession信息如果存儲(chǔ)在網(wǎng)站應(yīng)用服務(wù)器的緩存中,加臺(tái)服務(wù)器就不能用了,因此將Session解耦是解決此問(wèn)題的關(guān)鍵,下面介紹網(wǎng)站常見(jiàn)的Session管理手段。
1、Session復(fù)制
?????Session復(fù)制是最早企業(yè)應(yīng)用系統(tǒng)使用較多的一種服務(wù)集群Session管理機(jī)制,開(kāi)啟Session復(fù)制功能,即是在集群中的幾臺(tái)服務(wù)器之間同步Session對(duì)象,Java中好像JBoss有這個(gè)功能,.Net暫不知道。
?????優(yōu)勢(shì):Session信息讀取快,實(shí)現(xiàn)簡(jiǎn)單。
?????缺點(diǎn):集群規(guī)模較大時(shí),服務(wù)器之間Session復(fù)制會(huì)占用服務(wù)器資源和網(wǎng)絡(luò)資源,最后系統(tǒng)會(huì)不堪重負(fù)。
2、Session綁定?
?????Session綁定的方式,一般軟/硬均衡負(fù)載服務(wù)器都會(huì)提供此功能,例如:上篇文章Nginx的IPhash方式,均衡負(fù)載服務(wù)器利用Hash算法將同一IP分配到同一臺(tái)服務(wù)器上,即Session綁定在某臺(tái)特定服務(wù)器上,保證Session總能在這臺(tái)服務(wù)器上獲得,又稱作為會(huì)話黏滯。
?????缺點(diǎn):如果某臺(tái)服務(wù)器宕機(jī),那么這臺(tái)服務(wù)器上面的Session也就不存在了,用戶請(qǐng)求切換到其他服務(wù)器上因?yàn)闆](méi)有Session而出錯(cuò)。
?
3、利用Cookie記錄Session
?????通過(guò)Cookie記錄Session信息是大部分網(wǎng)站采用的方法,這種方式只要Cookie不濫用,也是非常好非常成熟的方案。Cookie記錄Session就是把一些狀態(tài)信息放到了客戶端,每次請(qǐng)求都要傳輸?shù)椒?wù)器。
?????優(yōu)勢(shì):這種方法簡(jiǎn)單易實(shí)現(xiàn),可用性高,支持服務(wù)器橫向拓展,方案成熟
?????缺點(diǎn):安全性問(wèn)題,Cookie有大小限制,而且每次請(qǐng)求傳輸Cookie會(huì)影響性能
?
4、Session服務(wù)器
?????Session服務(wù)器的方式管理Session,是一種非常好的解決方案,因?yàn)镾ession是為了業(yè)務(wù)需要Http狀態(tài)而產(chǎn)生,而分布式網(wǎng)站設(shè)計(jì)中提倡Http無(wú)狀態(tài),為了滿足這一設(shè)計(jì),Session服務(wù)器是將有狀態(tài)的Session信息與無(wú)狀態(tài)的應(yīng)用服務(wù)器相分離,再針對(duì)不同服務(wù)器的不同特性進(jìn)行設(shè)計(jì)。例如:我們將Session信息存入到Redis中,那么Redis的集群配置、穩(wěn)定性設(shè)置都有很多好的解決方案,如果將Session存入到Memcache,那么Memcache的集群配置、穩(wěn)定性設(shè)置也會(huì)有很多成熟案例。這樣我們就將一些問(wèn)題簡(jiǎn)單化,如果我們單獨(dú)應(yīng)用.Net的Session,我們需要了解更多.Net深層次的東西并加以改造來(lái)保證其可用和穩(wěn)定,越深層的東西越需要時(shí)間和閱歷,而如果將Session存儲(chǔ)介質(zhì)轉(zhuǎn)移到Redis中,Redis集群方案、管理工具都非常成熟,只需要配置配置就解決了Session的問(wèn)題,何樂(lè)而不為呢。
?????優(yōu)勢(shì):可用性高、安全性高、伸縮性好、性能高、信息大小無(wú)限制
?
三、.Net Core+Redis+Nginx實(shí)現(xiàn)Session分布式共享
1、前期準(zhǔn)備&環(huán)境
??????(1)Vs2017??? (2).Net Core 1.1? (3) Win 7? (4)ubuntu 16.04
2、.Net Core簡(jiǎn)介
?????? 隨著互聯(lián)網(wǎng)的發(fā)展,在當(dāng)今中國(guó)市場(chǎng)(外國(guó)不大清楚)開(kāi)源、跨平臺(tái)是衡量一門語(yǔ)言、技術(shù)好壞的重要指標(biāo)之一,微軟為了推動(dòng).Net開(kāi)源及跨平臺(tái),.Net Core隨之誕生。
???????詳見(jiàn)大牛的文章:.NET Core與.NET Framework、Mono之間的關(guān)系
?????? 下面說(shuō)說(shuō).Net Core給我的初步的感受:
???????? 1).Net Core并沒(méi)有顛覆之前C#語(yǔ)法
????????? 通俗講就是之前說(shuō)中國(guó)話(C#),現(xiàn)在還是說(shuō)中國(guó)話,只是說(shuō)話的環(huán)境變了。
???????? 2).Net Core因?yàn)閯偲鸩?#xff0c;API變了或者少了很多
????????? 通俗講就是說(shuō)話環(huán)境變了,而且里面有好多你沒(méi)見(jiàn)過(guò)的東西,你不知道用什么官方詞語(yǔ)來(lái)描述,因?yàn)楣俜秸谡蚁嚓P(guān)詞來(lái)描述這些新東西。
???????? 3)脫離IIS,跨平臺(tái)
????????? 通俗講就是微軟老媽為了不讓我們到了新環(huán)境餓著,怕離開(kāi)現(xiàn)在這個(gè)環(huán)境(Windows+IIS)之后不知道怎么生存。于是,教會(huì)了我們語(yǔ)言(C#),給了我們掙錢的工具(.Net Core+Kestrel),說(shuō)了一句“去吧孩子,自己奮斗去吧,稍等,別忘了把這張Visa卡帶上(.Net Core SDK),我會(huì)定期給你打錢的。”
???????? 4)NuGet越來(lái)越重要
????????? NuGet經(jīng)過(guò)幾年的發(fā)展,越來(lái)越成熟,.Net Core開(kāi)源組件獲取的主要方法,通過(guò)NuGet可以下載各種中間件和組件,而且方便快捷(除了有時(shí)候斷網(wǎng),但是可以使用國(guó)內(nèi)鏡像),NuGet就像微軟老媽給咱們的一個(gè)通訊錄,并告訴咱們,如果你在某些方面需要幫助的時(shí)候,可以通過(guò)NuGet找到你的七大姑八大姨來(lái)幫忙。
3、拓?fù)鋱D
????????? 根據(jù)之前文章中成功的經(jīng)驗(yàn),簡(jiǎn)單改造一下,中間一個(gè)Windows系統(tǒng)和一個(gè)Ubuntu系統(tǒng)承載著.Net Core程序,有人會(huì)問(wèn)Windows那個(gè)咋不來(lái)個(gè)IIS啊,我要說(shuō)的是.Net Core實(shí)行走出去的原則,基本脫離IIS,如果IIS上面想部署.Net Core程序的話,需要安裝同樣的應(yīng)用程序,并且站點(diǎn)配置的應(yīng)用程序池也要變成“無(wú)托管代碼”。
4、開(kāi)發(fā).Net Core程序使用Session
4-1、創(chuàng)建一個(gè)Web程序
????????? 用Vs2017創(chuàng)建一個(gè).Net Core的Web應(yīng)用程序,且這個(gè)應(yīng)用程序不包含身份驗(yàn)證信息
???????? 創(chuàng)建完如下
4-2、.Net Core調(diào)用Session
????????.Net Core使用Session,需要引用相關(guān)Session的NuGet包,網(wǎng)上一查,發(fā)現(xiàn).Net Core的官方Session組件類似一個(gè)中間件,并且官方支持Redis。
?????????注意:.Net Core的Mvc不能直接使用Session,如果你在程序里面寫了個(gè)HttpContext.Session就會(huì)出現(xiàn)如下錯(cuò)誤:Session has not been configured for this application or request.
4-2-1、Microsoft.AspNetCore.Session
?????????.Net Core使用Session必須安裝Microsoft.AspNetCore.Session,他的NuGet包安裝如下圖:
4-2-2、修改Startup.cs讓Session可用
??????????在相應(yīng)位置加入高亮代碼services.AddSession();?app.UseSession();
public void ConfigureServices(IServiceCollection services){// Add framework services.services.AddMvc();services.AddSession();} public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {loggerFactory.AddConsole(Configuration.GetSection("Logging"));loggerFactory.AddDebug();if (env.IsDevelopment()){app.UseDeveloperExceptionPage();app.UseBrowserLink();}else{app.UseExceptionHandler("/Home/Error");}app.UseStaticFiles();app.UseSession();app.UseMvc(routes =>{routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");}); }4-2-3、Session寫入和讀取
??????????Session的讀取方式,與.Net有所不同,寫法如下,并且Session的HttpContext.Session.SetString或者HttpContext.Session.Set方法分別支持字符串和Byte數(shù)組,所以復(fù)雜實(shí)體需要轉(zhuǎn)化成Json存入Session中。
【Session 寫入方法】
HttpContext.Session.SetString("key", "strValue");【Session 讀取方法】
HttpContext.Session.GetString("key")5、Session存儲(chǔ)介質(zhì)更換為Redis
5-1、首先配置Redis
詳細(xì)配置方式見(jiàn):Session分布式共享 = Session + Redis + Nginx
redis-server redis.windows.conf詳細(xì)配置方式見(jiàn):Session分布式共享 = Session + Redis + Nginx
5-2、安裝Microsoft.Extensions.Caching.Redis.Core
?????? NuGet中搜索Microsoft.Extensions.Caching.Redis.Core并安裝,此NuGet包是對(duì)Caching的拓展,即可以更換Caching存儲(chǔ)介質(zhì)
5-3、appsettings.json配置Redis連接字符串
???????appsettings.json配置Redis連接字符串(相當(dāng)于web.config里面配置appsetting節(jié)點(diǎn)),注意:添加位置要在Logging上面,否則讀不到,添加代碼為下面的高亮部分
{"Data": "RedisConnection",
"ConnectionStrings": {
"RedisConnection": "192.168.8.138:6379"
}, "Logging": {"IncludeScopes": false,"LogLevel": {"Default": "Warning"}} }
5-4、Startup.cs的ConfigureServices方法中添加引用
public void ConfigureServices(IServiceCollection services){// Add framework services.services.AddMvc();services.AddDistributedRedisCache(option =>{ ? ? ? ? ? ? ? ? ? ?//redis 數(shù)據(jù)庫(kù)連接字符串
? ? ? ? ? ? ? ? ? ?option.Configuration = Configuration.GetConnectionString("RedisConnection");
?? ? ? ? ? ? ? ? ? //redis 實(shí)例名
? ? ? ? ? ? ? ? ? ?option.InstanceName =?"master";
? ? ? ? ? ? ??});
? ? ? ? ? ? ??services.AddSession();
? ? ? ? ? }
?????????頁(yè)面運(yùn)行HttpContext.Session.GetString("key"),然后用Redis管理工具RedisDesktopManager查詢Session是否入庫(kù)。
5-5、發(fā)布前指定IP和端口(重要)?
?????????如果你沒(méi)有看這個(gè)步驟,繼續(xù)下面發(fā)布步驟,等你發(fā)布時(shí)候,你會(huì)發(fā)現(xiàn)一個(gè)尷尬的問(wèn)題,就是你用IP訪問(wèn)不了你的網(wǎng)站,用localhost可以訪問(wèn),.Net Core默認(rèn)是5000端口,端口占用也會(huì)讓你的網(wǎng)站訪問(wèn)不了。
?????????只需要在Program.cs中添加高亮代碼即可,細(xì)心地人已經(jīng)看到.UseUrls(new?string[] {?})?傳入的是個(gè)數(shù)組,那么這里定義多個(gè)網(wǎng)站,當(dāng)你執(zhí)行時(shí)候dotnet命令時(shí)候,多個(gè)網(wǎng)站都會(huì)啟動(dòng)。
public static void Main(string[] args){var host = new WebHostBuilder() ? ? ? ? ? ? ? ? ? //增加處,*號(hào)表示ip?? ? ? ? ? ? ? ? ? .UseUrls(new?string[] {?"http://*:7201"?}) .UseKestrel().UseContentRoot(Directory.GetCurrentDirectory()).UseIISIntegration().UseStartup<Startup>().UseApplicationInsights().Build();host.Run();}
6、.Net Core 發(fā)布
6-1、Windows安裝.Net Core發(fā)布環(huán)境[10.2.107.100]
???????? 1)安裝Windows Server Hosting (x64 & x86),相當(dāng)于IIS,注意安裝時(shí)候請(qǐng)聯(lián)網(wǎng)(好像是自動(dòng)下載sdk,具體沒(méi)仔細(xì)研究)。
????????2)輸入dotnet命令驗(yàn)證,如果“報(bào)’dotnet’不是內(nèi)部或者外部命令”請(qǐng)找到“C:\Program Files\dotnet”文件夾中的dotnet.exe,用cmd來(lái)調(diào)用dotnet.exe來(lái)運(yùn)行,或者添加系統(tǒng)環(huán)境變量(window中cmd命令可以節(jié)省在編寫命令時(shí)候可以.exe,即命令dotnet就是dotnet.exe)
???????【坑1】
?????????在win7下提示一下錯(cuò)誤:Failed to load the dll from [C:\Program Files\dotnet\host\fxr\1.0.1\hostfxr.dll], HRESULT: 0x80070057
?????????解決方法:
?????????需要安裝補(bǔ)丁:KB2533623
????????下載地址如下:
?????????https://support.microsoft.com/en-us/kb/2533623?
??????【坑2】
?????????注意.net Core版本,本文主要是用的.net Core 1.1.1開(kāi)發(fā)的,下面兩個(gè)截圖是版本按錯(cuò)了出的錯(cuò)誤信息
6-2、Ubuntu安裝.Net Core發(fā)布環(huán)境[10.2.107.46]
?????????Ubuntu安裝.Net Core官方寫的很詳細(xì)了,照著做即可,千萬(wàn)別抵觸Linux系統(tǒng),抵觸的話那就別用.Net Core了,如果不知道Ubuntu和Linux的關(guān)系的話請(qǐng)百度。
???????? 最后驗(yàn)證dotnet命令是否可以使用。
6-3、發(fā)布網(wǎng)站
???????在項(xiàng)目上右鍵->發(fā)布…
???????點(diǎn)擊發(fā)布按鈕,生成的文件如下(SessionTest為應(yīng)用程序名)
??????? 好了,有了這些文件,我們只需要把這些文件扔到服務(wù)器上就成了,但是怎么啟動(dòng)呢?通過(guò)查詢,網(wǎng)上說(shuō)只要用dotnet命令就成。繼續(xù)實(shí)踐…
?? ? ? ?說(shuō)明:我的項(xiàng)目叫做生成了這個(gè)為主要的dll,也是程序的入口。
?? ? ? ?大家都知道.Net Core是跨平臺(tái)的,不同系統(tǒng)的服務(wù)器環(huán)境配置好了,網(wǎng)上查詢說(shuō)是使用dotnet命令啟動(dòng)網(wǎng)站,那么可以推斷出幾個(gè)平臺(tái)的dotnet命令是一樣的。
6-3-1、Windows啟動(dòng).Net Core網(wǎng)站[10.2.107.100:7201]
???????? 啟動(dòng).Net Core網(wǎng)站的命令很簡(jiǎn)單,安裝好發(fā)布環(huán)境的應(yīng)用程序,C:\Program Files\dotnet目錄如下(如果dotnet命令不能用,可以直接調(diào)用dotnet.exe這個(gè)應(yīng)用程序。)
?????????將生成好的網(wǎng)站復(fù)制到服務(wù)器上
?cmd命令找到PublishOutput
cd C:\PublishOutputdotnet運(yùn)行網(wǎng)站命令
dotnet SessionTest.dll成功以后(之后再編譯運(yùn)行,會(huì)提示下面截圖)
訪問(wèn)http://10.2.107.100:7201/(如果一臺(tái)機(jī)子有多個(gè)網(wǎng)卡多個(gè)IP,其他IP的7201端口也是個(gè)獨(dú)立網(wǎng)站)
?
6-3-2、Ubuntu啟動(dòng).Net Core網(wǎng)站[10.2.107.46:7201]
想辦法將發(fā)布的程序復(fù)制到Ubuntu上面去,我測(cè)試使用的VBox虛擬機(jī)。
具體方法傳送門:virtualbox中ubuntu和windows共享文件夾設(shè)置
dotnet SessionTest.dll訪問(wèn)http://10.2.107.46:7201/
7、Nginx配置
7-1、網(wǎng)站端口修改
????????nginx.conf配置修改
????????listen?? 80; 改成?listen?? 81; 因?yàn)橐话愣急?0都被使用。
server {listen 81;…… }7-2、增加負(fù)載均衡
??nginx.conf中添加upstream節(jié)點(diǎn)
upstream Jq_one {?? ? ? server?10.2.107.100:7201;?
? ? ? ?server?10.2.107.46:7201; } server { ..... }
?
7-3、location節(jié)點(diǎn)修改
location / {root html;index index.aspx index.html index.htm;#其中jq_one 對(duì)應(yīng)著upstream設(shè)置的集群名稱proxy_pass http://Jq_one; #設(shè)置主機(jī)頭和客戶端真實(shí)地址,以便服務(wù)器獲取客戶端真實(shí)IPproxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }7-4、Nginx啟動(dòng)命令
??????? C:\server\nginx-1.0.2>start nginx
??????? 或
??????? C:\server\nginx-1.0.2>nginx.exe
7-5、Nginx重新載入命令
??????C:\server\nginx-1.0.2>nginx.exe -s reload
?
四、黎明前的黑暗-MachineKey
?
????? 本以為做了上述準(zhǔn)備和相關(guān)代碼編寫,就能夠?qū)崿F(xiàn)Session共享了,結(jié)果我想的太簡(jiǎn)單了,應(yīng)用程序發(fā)布后并不能實(shí)現(xiàn)Session共享,難道分布式共享下Session需要特殊處理?.Net我是怎么實(shí)現(xiàn)的,它們的方法應(yīng)該方法類似。我突然想到了MachineKey這個(gè)東西,之前在.Net版本分布式共享時(shí)候需要添加這個(gè)東西,評(píng)論也有人問(wèn)我什么要加MachineKey。后來(lái)只能搜索.Net Core Machinekey關(guān)鍵詞,找到了以下幾篇文章做參考。
??????搭建分布式 ASP.NET Core Web
??????ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)
??????坎坷路:ASP.NET Core 1.0 Identity 身份驗(yàn)證(中集)
? ????net core 1.0 實(shí)現(xiàn)負(fù)載多服務(wù)器單點(diǎn)登錄
??????此問(wèn)題屬于數(shù)據(jù)安全問(wèn)題,微軟在開(kāi)發(fā).Net Core中延續(xù)了之前的設(shè)計(jì),采用數(shù)據(jù)保護(hù)(Data Protection)方式對(duì)一些內(nèi)部數(shù)據(jù)進(jìn)行加密解密設(shè)計(jì),如:Session、Cookie等(遠(yuǎn)不止這些)。這樣可以保證數(shù)據(jù)的真實(shí)性、完整性、機(jī)密性、隔離性。數(shù)據(jù)安全必然離不開(kāi)加解密算法,大家想一下之前.Net的WebFrom中的ViewState,它最終解析到Html頁(yè)面是個(gè)hidden標(biāo)簽里面有一串很復(fù)雜的字符串,這個(gè)字符串是被數(shù)據(jù)保護(hù)(Data Protection)機(jī)制加密過(guò)的。Session也一樣,大家可以看看Session存到Redis中啥樣,見(jiàn)下圖:
?????? 數(shù)據(jù)保護(hù)(Data Protection)有個(gè)特性是隔離性,大家可以想象一下,數(shù)據(jù)保護(hù)核心是加密解密,常見(jiàn)的加密方式有對(duì)稱加密和非對(duì)稱加密,上一篇做分布式共享時(shí)候,兩臺(tái)機(jī)子拷貝了同樣的MahcineKey,那么他的內(nèi)部加密猜測(cè)好像是對(duì)稱加密,MachineKey直譯中文為“機(jī)器鑰匙”在聯(lián)想隔離性,那么可以推斷出來(lái)不同機(jī)子密鑰是不同的,那么MachineKey的作用是統(tǒng)一不同機(jī)子的密鑰。(吐血中…….這個(gè)只是個(gè)猜測(cè),詳細(xì)原理請(qǐng)參考專業(yè)文章)
1、提取.Net Core的MachineKey
? ? ? ??.Net Core的MachineKey存儲(chǔ)是以key-xxxx-xxxx-xxxx-xxxx.xml的形式存儲(chǔ)的,那如何提取這個(gè)xml信息呢?
?????? Startup.cs的ConfigureServices添加下圖高亮代碼
public void ConfigureServices(IServiceCollection services){ ? ? ? ? ? ? ? //抽取key-xxxxx.xml?? ? ? ? ? ? services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(@"D:\XML")); services.AddSession();services.AddDistributedRedisCache(option =>{//redis 數(shù)據(jù)庫(kù)連接字符串option.Configuration = Configuration.GetConnectionString("RedisConnection");//redis 實(shí)例名option.InstanceName = "master";});services.AddMvc();}
?????? 查看D:\Xml里的xml文件
?
2、重寫IXmlRepository接口固定Key
?????? 在項(xiàng)目中添加CustomXmlRepository.cs類,其中keyContent中填寫key.xml內(nèi)容,注意:里面的幾個(gè)時(shí)間(現(xiàn)在還不能確定expirationDate對(duì)項(xiàng)目是否有影響),有人問(wèn)我KeyContent能否從文件里讀,回答是可以,但是ubuntu的文件路徑保準(zhǔn)不是Windows的d:\之類的,需要使用Linux的寫法,所以干脆字符串來(lái)的快。
using Microsoft.AspNetCore.DataProtection.Repositories; using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq;namespace SessionTest {public class CustomXmlRepository : IXmlRepository{private readonly string keyContent = @"<?xml version='1.0' encoding='utf-8'?> <key id='9108538d-9ea4-45fb-a690-438c8d788619' version='1'><creationDate>2017-04-27T06:15:07.2194692Z</creationDate><activationDate>2017-04-27T06:15:07.1844647Z</activationDate><expirationDate>2017-07-26T06:15:07.1844647Z</expirationDate><descriptor deserializerType='Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'><descriptor><encryption algorithm='AES_256_CBC' /><validation algorithm='HMACSHA256' /><masterKey p4:requiresEncryption='true' xmlns:p4='http://schemas.asp.net/2015/03/dataProtection'><!-- Warning: the key below is in an unencrypted form. --><value>HOz58FE6STtDHlMo2ZONoPgPTOOjRPikRWXmHOwNDS5o6NPb4hlgl/DxXUhat66soovBUFy1APXCQ4z30DDPyw==</value></masterKey></descriptor></descriptor> </key>";public virtual IReadOnlyCollection<XElement> GetAllElements(){return GetAllElementsCore().ToList().AsReadOnly();}private IEnumerable<XElement> GetAllElementsCore(){yield return XElement.Parse(keyContent);}public virtual void StoreElement(XElement element, string friendlyName){if (element == null){throw new ArgumentNullException(nameof(element));}StoreElementCore(element, friendlyName);}private void StoreElementCore(XElement element, string filename){}} }修改Startup.cs文件中的ConfigureServices方法加載自定義的CustomXmlRepository類
public void ConfigureServices(IServiceCollection services){抽取key-xxxxx.xml//services.AddDataProtection()// .PersistKeysToFileSystem(new DirectoryInfo(@"D:\XML"));services.AddSingleton<IXmlRepository, CustomXmlRepository>(); ? ? ? ? ? ? ? services.AddDataProtection(configure?=> {configure.ApplicationDiscriminator = "newP.Web"; });services.AddSession();services.AddDistributedRedisCache(option =>{//redis 數(shù)據(jù)庫(kù)連接字符串option.Configuration = Configuration.GetConnectionString("RedisConnection");//redis 實(shí)例名option.InstanceName = "master";});services.AddMvc();}五、實(shí)現(xiàn)效果演示
? ? ??? ?演示效果說(shuō)明
? ? ??? ?本機(jī)127.0.0.1也為10.2.107.100,因?yàn)殡娔X性能有限,沒(méi)有弄windows虛擬機(jī),只弄了10.2.107.46這臺(tái)Linux虛擬機(jī)。
? ? ??? ?MachineKey的這個(gè)實(shí)現(xiàn)思路也可以用到.Net Core的身份驗(yàn)證上。
? ? ?????UNC文件也可以實(shí)現(xiàn)Session共享方式
? ? ??? ?原理就是Windows和Linux通過(guò)文件共享和掛載的方式Key.xml共享一個(gè)文件,但是總覺(jué)得有點(diǎn)怪怪的,共享文件會(huì)不會(huì)被別人惡意篡改,所以最后采用重寫的方式實(shí)現(xiàn)。
? ? ??? ?對(duì)UNC方式感興趣的請(qǐng)看:搭建分布式 ASP.NET Core Web
?
?
?六、后記&感悟
???????? 希望通過(guò)本文,讓大家對(duì)網(wǎng)站的可用性中有個(gè)簡(jiǎn)單認(rèn)識(shí),并了解到Session存入Redis中的優(yōu)勢(shì)。本文介紹的網(wǎng)站可用性內(nèi)容中的冰山一角,還有許多知識(shí)需要我們?nèi)W(xué)習(xí)和積累。
??????? .Net Core版本的Session分布式共享,讓我們對(duì).Net Core有了初步了解,.Net Core的高性能、跨平臺(tái)、開(kāi)源,讓許多人改變了對(duì).Net的看法,但是.Net Core在中國(guó)市場(chǎng)的路還有很長(zhǎng)要走,我認(rèn)為.Net Core并不是扭轉(zhuǎn).Net語(yǔ)言在中國(guó)市場(chǎng)占有率的銀彈。真正的銀彈也許是我們這些天天寫程序的.Neter,即使是微軟大量宣傳.Net Core、成功案例漫天飛,我們不去學(xué)習(xí)、不去了解新知識(shí),我們最終會(huì)被淘汰。語(yǔ)言只是工具,只有通過(guò)不斷學(xué)習(xí)和努力,將知識(shí)消化、吸收并最終分享給別人才會(huì)有最大的收獲,我們?cè)谑致房诿悦V畷r(shí),為何不去學(xué)習(xí)新的知識(shí)和方法提升自身的經(jīng)驗(yàn)和閱歷。我經(jīng)常會(huì)跟別人說(shuō),工作前幾年最重要的不是知識(shí),而是你做事的風(fēng)格和為目標(biāo)持之以恒的信念,俗話說(shuō)“江山易改,本性難移”,如果不好的工作態(tài)度和方法變成了你的工作習(xí)慣,即使換了語(yǔ)言、換了工作甚至轉(zhuǎn)了行,都會(huì)對(duì)你的職業(yè)發(fā)展有很大影響。好的習(xí)慣一定要堅(jiān)持,有些事堅(jiān)持一天可以、堅(jiān)持兩天可以、但是堅(jiān)持三個(gè)月以上,卻變成了無(wú)法完成的任務(wù),更別提幾年了,“不積跬步,無(wú)以至千里”,只有堅(jiān)持每天去磨練自己才能有所成長(zhǎng),因?yàn)槲抑牢也皇翘觳?#xff0c;需要后天的努力才能成長(zhǎng)。
????? “踏踏實(shí)實(shí)做人,認(rèn)認(rèn)真真做事”我堅(jiān)信自己的努力,一定會(huì)有回報(bào)的,只是現(xiàn)在還沒(méi)有抓住機(jī)遇。最后,向那些奮斗在一線使用.Net Core開(kāi)發(fā)的人員致敬。
??????? 以上總結(jié)是我熬的味道濃郁的心靈雞湯,可話說(shuō)啥時(shí)候能改掉我工作外的拖延癥啊,這篇文章一直拖拖拖,論文一直拖拖拖,學(xué)英語(yǔ)拖拖拖,還有好多事要做可一直也是拖拖拖,悲劇啊。。。突然發(fā)現(xiàn)鴨梨山大啊,壞習(xí)慣不好改啊!請(qǐng)大家引以為戒!當(dāng)然別做工作狂,身體健康更重要,有時(shí)間多陪陪家里人。
????????個(gè)人觀點(diǎn),有可能因?yàn)橹R(shí)和閱歷的原因,分析片面,請(qǐng)多諒解。
?
七、參考文章
? ? ? ? ?ASP.NET Core 使用 Redis 和 Protobuf 進(jìn)行 Session 緩存
? ? ? ??.Net Core Session使用
? ? ? ??Asp.net Core 使用Redis存儲(chǔ)Session
? ? ? ??Using Sessions and HttpContext in ASP.NET Core and MVC Core
? ? ? ??.NET Core與.NET Framework、Mono之間的關(guān)系
? ? ? ??virtualbox中ubuntu和windows共享文件夾設(shè)置??
? ? ? ??搭建分布式 ASP.NET Core Web
? ? ? ??ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)
? ? ? ??坎坷路:ASP.NET Core 1.0 Identity 身份驗(yàn)證(中集)
? ? ? ??net core 1.0 實(shí)現(xiàn)負(fù)載多服務(wù)器單點(diǎn)登錄
?
轉(zhuǎn)載于:https://www.cnblogs.com/yanglang/p/6805575.html
總結(jié)
以上是生活随笔為你收集整理的详解Session分布式共享(.NET CORE版)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 中行随心女人卡怎么样?丰厚权益等你来享
- 下一篇: XML Schema 基本结构