Session分佈式共享 = Session + Redis + Nginx

1、Sessionhtml


一、Session 介紹nginx

      我相信,搞Web開發的對Session必定再熟悉不過了,因此我就簡單的介紹一下。git

      Session:在計算機中,尤爲是在網絡應用中,稱爲「會話控制」。 每一個用戶(瀏覽器)首次與web服務器創建鏈接時,就會產生一個Session,同時服務器會分配一個SessionId給用戶的瀏覽器。咱們能夠用Fiddler查看cookies中,會看到有一個ASP.Net_SessionId的cookie。你們都知道Http是無狀態請求,可是ASP.Net中的Session彷彿又讓Http請求變得有狀態,其核心就在於這個叫ASP.Net_SessionId的cookie。你們能夠想象一下,這個至關於數據庫的Key,服務器那邊再有個Session內容緩存表,是否是Session的內容就很容易獲得了?固然Session不是那麼簡單,但Session原理不是本文介紹重點,因此請你們自行度娘。程序員

image

 

二、又愛又恨的Sessiongithub

      剛接觸程序開發的人必定愛死Session了,由於Session讓Http從無狀態變成有狀態了,頁面之間傳值、用戶相關信息、一些不變的數據、甚至於查出來的DataTable也能夠放進去,取值的時候只須要Session[Key]便可,真是方便極了。Session真是個利器,人擋殺人佛擋殺佛,但任何事物被封爲利器基本也是雙刃劍,Session的許多問題咱們不得不去面對。web

【常見問題請見下圖】redis

      image

      我相信一見到這個問題,老程序員都會內心一哆嗦,Session是致使這個緣由之一,你們也會想到這個情景,「我去,是否是Session又丟了,讓用戶從新登陸」,事故報告中會填寫:.NET規定,用戶登錄後長時間沒操做致使的。解決方案爲:把Session時間調到9999。數據庫

      結果該發生的仍是繼續發生着,Session照樣丟失。windows

常見Session丟失緣由】瀏覽器

      一、Session超時,用戶打開頁面,頁面長時間不操做會致使此緣由

      二、IIS應用程序池回收,或者重啓

      三、Web.Config修改,即IIS應用程序池重啓

      四、dll被替換或者動態頁面修改,即IIS應用程序池重啓

      五、殺毒軟件對.config文件進行掃描,可能會致使IIS應用程序池回收

      六、用戶瀏覽器禁用cookie

      七、其餘緣由

      其餘緣由有點不負責,可是好多程序員沒法查明是什麼緣由致使Session丟失,但Session丟失我歸結爲兩大類,一個是數據的Key丟了,一個是Session內容數據庫的丟了,你們這樣就好理解了,用戶瀏覽器禁用cookie必定是Key沒了。IIS應用程序池回收一定會致使Session的內容緩存表丟失,固然還有一些其餘緣由。

三、解決Session丟失的漫長路

      解決過Session丟失的都會用到這幾種方法

          一、InProc:將Session存到進程內。

          二、StateServer:將Session存到獨立的狀態服務中(Asp.Net State Service)。

          三、SqlServer:將Session存到SqlServer中。

          四、Cookieless:設置客戶端Session存儲的方式。

     用了這些方法以後,有的是該丟還丟,有的是穩定了速度卻慢了。

     你們也注意到了,還有個這個Custom自定義模式,有人會說:「除了大牛,有幾個敢寫的啊,寫出來有問題怎麼辦,算了算了。」 等等,你們不要還停留在非開源模式下解決問題的思想,找找開源項目,必定能找到的,有人說ASP.NET上哪裏找開源啊,很是簡單NuGet,若是想了解開源,必定要學會使用NuGet。

 

2、Redis


一、前言  

     上文說了那麼多,有人必定會說我是來解決Session丟失的,上哪裏來的Session分佈式共享,標題黨,我仍是繼續用個人cookie吧。

     我要說的是,幾年前,在Stack Overflow上找到了這個方法解決了丟失問題,以後,發現這種方法還能夠實現Session分佈式共享。那就是運用Custom自定義模式,將Session持久化到Memcache和Redis中。Session丟失、以及持久化到SqlServer數據的性能問題也隨之解決。

     此種方法很適合老項目中大量應用Session而致使法搞成分佈式而苦惱的.NET開發人員使用。由於頗有可能老項目維護過程當中,身邊的JAVA團隊、PHP團隊,正在重構你的項目。

二、RedisSessionProvider

     正文開始,首先,沿着咱們的思路Session持久化到Memcache或者Redis中,經過nuget下載 RedisSessionProvider(別問我怎麼找到的,由於我英文過了四級,我會使用度娘,嘿嘿)

image

 

【web.config配置以下】

<system.web>
    <sessionState mode="Custom" customProvider="RedisSessionProvider">
      <providers>
        <add name="RedisSessionProvider" type="RedisSessionProvider.RedisSessionStateStoreProvider, RedisSessionProvider"/>
      </providers>
    </sessionState>
</system.web>

【Global.asax】

    void Application_Start(object sender, EventArgs e)
    {
       
        StackExchange.Redis.ConfigurationOptions redisConfigOpts = StackExchange.Redis.ConfigurationOptions.Parse("192.168.8.138:6379");
        RedisSessionProvider.Config.RedisConnectionConfig.GetSERedisServerConfig = (HttpContextBase context) =>
        {
            return new KeyValuePair<string, StackExchange.Redis.ConfigurationOptions>(
                "DefaultConnection",                
                redisConfigOpts);
        };

    }

存儲方法】

   Session["Test"] = "aa";

調用方法】

   string str = Session["Test"].ToString()

 !前方坑,請注意!

    若是你配置好Redis,而且作好上面這些配置,運行會出現如下問題,請更新RedisSessionProvider的依賴包StackExchange.Redis到最新。

imageimage

 

三、Redis安裝

3-一、Redis for windows下載

     若是會配置Redis的同窗,請略過此章節,直接進入Nginx。

     Redis下載:https://github.com/MSOpenTech/redis

image

!此處爲坑,請注意!

     修改Redis.windows.conf,若是不修改,遠程不能訪問Redis

     一、將bind 127.0.0.1 改爲了bind 0.0.0.0。注意:進入生產環境時候,要啓用密碼,不然會是Redis漏洞,具體請自行度娘和本身公司的運維阿牛

     2protected-mode yes 改爲 protected-mode no

     詳細修改的傳送門: redis開啓遠程訪問

3-二、啓動Redis

redis-server redis.windows.conf

image     上圖爲redis啓動成功,默認6379,能夠經過redis-cli進行測試,看別的機子可否訪問。還能夠在找個redis可視化工具看看裏面存了啥,也能夠監控Session是否持久化到Redis中了。

3-三、驗證Session是否持久化到Redis

     運行RedisSessionProvider這個項目。同一個IIS下,同域名,不一樣IP,同一瀏覽器,不一樣端口一個是2459,一個是2490。

     1[6]

注意

     不一樣瀏覽器SessionId是不一樣的。必須保證SessionId,測試必須是同一個瀏覽器進程分出的不一樣子標籤才能夠,這樣SessionId是共享的。

image

     感受成功了,讓咱們看看這樣的拓撲圖:

image

     囧……這是啥玩意?個人分佈式呢?這個拓撲圖很顯然不是分佈式啊,還兩個IP,我還要在前面作個路由登陸頁面?這時Nginx該登場了。

 

3、Ngnix 


一、Ngnix安裝&下載

      下載地址:http://nginx.org/

二、nginx.conf配置修改

image

2-一、【接口修改】

       listen   80; 改爲  listen   1100; 由於通常都被80都被使用。

image

2-二、【增長負載均衡】

upstream  Jq_one {  

     server 127.0.0.1:8770;
     server 192.168.8.138:7777;
} 
server {
.....
}

 

image

2-三、【location節點修改】

location / {
            root   html;
            index  index.aspx index.html index.htm;
            #其中jq_one 對應着upstream設置的集羣名稱
            proxy_pass         http://Jq_one; 
            #設置主機頭和客戶端真實地址,以便服務器獲取客戶端真實IP
            proxy_set_header   Host             $host; 
            proxy_set_header   X-Real-IP        $remote_addr; 
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

2-四、【Nginx啓動命令】

        C:\server\nginx-1.0.2>start nginx

        或

        C:\server\nginx-1.0.2>nginx.exe

 

2-五、【Nginx從新載入命令】

        C:\server\nginx-1.0.2>nginx.exe -s reload

2-六、【參考文章】

         詳細配置傳送門:nginx+iis實現負載均衡

4、Session分佈式共享

一、拓撲圖

image

         經過Nginx+Redis實現對Session的分佈式共享功能。經過測試,發現Session分佈式共享共有兩種解決方案。

 

二、利用Nginx的Ip_Hash進行Session分佈式共享

         使用nginx將同一ip的請求分配到固定服務器,修改以下。ip_hash會計算ip對應hash值,而後分配到固定服務器

upstream Jq_one{
     server 127.0.0.1:8770;
     server 192.168.8.138:7777;
     ip_hash;
}

         效果能夠理解爲就是一個Ip,經過Nginx路由到IIS_1上面,在屢次請求,會一直在IIS_1上,不會路由到IIS_2上面。

2

 

 

三、利用MachineKey進行Session分佈式共享

     Ip_Hash在必定程度上解決了Session分佈式共享的問題,可是總感受沒有發揮出nginx均衡負載的功能,繼續改造

3-一、現將Ip_Hash去掉

    去掉Ip_Hash重啓Nginx,打開網站,點擊設置Session按鈕,結果報錯

image

3-二、web.config添加MachineKey

<machineKey
   validationKey="86B6275BA31D3D713E41388692FCA68F7D20269411345AA1C17A7386DACC9C46E7CE5F97F556F3CF0A07159659E2706B77731779D2DA4B53BC47BFFD4FD48A54"
   decryptionKey="9421E53E196BB56DB11B9C25197A2AD470638EFBC604AC74CD29DBBCF79D6046"
   validation="SHA1"
   decryption="AES"
/>

【注意

     負載均衡的兩個網站的MachineKey必須同樣,不然出問題。

3-三、演示

     下圖,你們能夠看到,服務器的Ip在不斷變化,而Session卻沒有丟失,至此實現了Session分佈式共享。3[8]

 

、參考文章

        redis開啓遠程訪問

        nginx+iis實現負載均衡

         ASP.NET性能優化之分佈式Session

        .Net分佈式架構(一):Nginx實現負載均衡

        .Net分佈式架構(二):基於Redis的Session共享

很是感謝上述文章,對本文的啓發,謝謝。

相關文章
相關標籤/搜索