詳解Session分布式共享(.NET CORE版)


一、前言&回顧


       在上篇文章Session分布式共享 = Session + Redis + Nginx中,好多同學留言問了我好多問題,其中印象深刻的有:nginx掛了怎么辦?采用Redis的Session方案與微軟Session方案相比,有什么優勢呢?Cookie也可以取代Session的,采用Redis的Session方案優勢在哪里?Nginx的iphash方式到底是什么?MachineKey有啥用?Net Core怎樣實現?

       那會兒看到大家的提問,我的回答也只是從應用層面回答,基本上的回答可以總結為:“別人這么做了,解決了這個問題,我用這個方法也解決了這個問題,原理請看鏈接。”很慚愧的說,那時的我並沒有完全理解他真正的優勢在哪里,只是憑着直覺和經驗知道這樣做比較好,知道當一部分東西不可控時候,將其解耦、可視化、集群就可以讓一個系統更加健壯,但沒有一個理論支撐。經過最近一段時間的查閱資料和閱讀書籍,對此有了深刻理解,本文將從網站架構的可用性角度對這種Session共享進行分析和講解,並用.net core再次實現這種架構模式。(Session分布式共享的net core版,因為工作沒有機會應用到生產環境,過往經驗就更別提了,所以只是研究性的,請大家注意,但園子里早有大牛寫出了相關文章,本文結束會將相關文章貼出)

二、網站可用性--Session管理


     可用性是網站架構中非常重要的一環,什么是可用性,說的簡單些,就是用戶隨時隨地打開這個網站,這個網站都能打開,並且里面的功能都能用。如果可用性不高會出現什么情況?大家想象一下春節在12306搶票的情景,網站各種崩潰,大家保准會想:要是有別的方式能買到票,我才不用12306這個破網站呢。這個例子有點極端,因為業務場景比較極端,當然,這種現象也不光是網站可用性這一環出了問題。但是一個網站三天兩頭打不開,要么是點開了里面的頁面到處是報錯頁面和操作無反應,你還會用這個網站么?我相信我們在瀏覽網站時候,只要不像12306這種壟斷業務的網站,出現不可用的情況,我們一定會離開尋找其他類似的網站。

     Session管理是網站可用性的內容之一,大家都知道Http是無狀態請求,即無法追蹤上次Http請求的相關信息,但是業務中大量需要將Http變為有狀態請求,Session就隨之產生了,可是在分布式網站設計中,無狀態請求才能實現網站的橫向拓展(增減應用服務器),因此又與Session相矛盾,因為Session信息如果存儲在網站應用服務器的緩存中,加台服務器就不能用了,因此將Session解耦是解決此問題的關鍵,下面介紹網站常見的Session管理手段。

1、Session復制

     Session復制是最早企業應用系統使用較多的一種服務集群Session管理機制,開啟Session復制功能,即是在集群中的幾台服務器之間同步Session對象,Java中好像JBoss有這個功能,.Net暫不知道。

     優勢:Session信息讀取快,實現簡單。

     缺點:集群規模較大時,服務器之間Session復制會占用服務器資源和網絡資源,最后系統會不堪重負。

image

2、Session綁定 

     Session綁定的方式,一般軟/硬均衡負載服務器都會提供此功能,例如:上篇文章Nginx的IPhash方式,均衡負載服務器利用Hash算法將同一IP分配到同一台服務器上,即Session綁定在某台特定服務器上,保證Session總能在這台服務器上獲得,又稱作為會話黏滯。

     缺點:如果某台服務器宕機,那么這台服務器上面的Session也就不存在了,用戶請求切換到其他服務器上因為沒有Session而出錯。

image

 

3、利用Cookie記錄Session

     通過Cookie記錄Session信息是大部分網站采用的方法,這種方式只要Cookie不濫用,也是非常好非常成熟的方案。Cookie記錄Session就是把一些狀態信息放到了客戶端,每次請求都要傳輸到服務器。

     優勢:這種方法簡單易實現,可用性高,支持服務器橫向拓展,方案成熟

     缺點:安全性問題,Cookie有大小限制,而且每次請求傳輸Cookie會影響性能

image

 

4、Session服務器

     Session服務器的方式管理Session,是一種非常好的解決方案,因為Session是為了業務需要Http狀態而產生,而分布式網站設計中提倡Http無狀態,為了滿足這一設計,Session服務器是將有狀態的Session信息與無狀態的應用服務器相分離,再針對不同服務器的不同特性進行設計。例如:我們將Session信息存入到Redis中,那么Redis的集群配置、穩定性設置都有很多好的解決方案,如果將Session存入到Memcache,那么Memcache的集群配置、穩定性設置也會有很多成熟案例。這樣我們就將一些問題簡單化,如果我們單獨應用.Net的Session,我們需要了解更多.Net深層次的東西並加以改造來保證其可用和穩定,越深層的東西越需要時間和閱歷,而如果將Session存儲介質轉移到Redis中,Redis集群方案、管理工具都非常成熟,只需要配置配置就解決了Session的問題,何樂而不為呢。

     優勢:可用性高、安全性高、伸縮性好、性能高、信息大小無限制

image

 

三、.Net Core+Redis+Nginx實現Session分布式共享


1、前期准備&環境

      (1)Vs2017    (2).Net Core 1.1  (3) Win 7  (4)ubuntu 16.04

2、.Net Core簡介

       隨着互聯網的發展,在當今中國市場(外國不大清楚)開源、跨平台是衡量一門語言、技術好壞的重要指標之一,微軟為了推動.Net開源及跨平台,.Net Core隨之誕生。

       詳見大牛的文章:.NET Core與.NET Framework、Mono之間的關系

       下面說說.Net Core給我的初步的感受:

         1).Net Core並沒有顛覆之前C#語法

          通俗講就是之前說中國話(C#),現在還是說中國話,只是說話的環境變了。

         2).Net Core因為剛起步,API變了或者少了很多

          通俗講就是說話環境變了,而且里面有好多你沒見過的東西,你不知道用什么官方詞語來描述,因為官方正在找相關詞來描述這些新東西。

         3)脫離IIS,跨平台

          通俗講就是微軟老媽為了不讓我們到了新環境餓着,怕離開現在這個環境(Windows+IIS)之后不知道怎么生存。於是,教會了我們語言(C#),給了我們掙錢的工具(.Net Core+Kestrel),說了一句“去吧孩子,自己奮斗去吧,稍等,別忘了把這張Visa卡帶上(.Net Core SDK),我會定期給你打錢的。”

         4)NuGet越來越重要

          NuGet經過幾年的發展,越來越成熟,.Net Core開源組件獲取的主要方法,通過NuGet可以下載各種中間件和組件,而且方便快捷(除了有時候斷網,但是可以使用國內鏡像),NuGet就像微軟老媽給咱們的一個通訊錄,並告訴咱們,如果你在某些方面需要幫助的時候,可以通過NuGet找到你的七大姑八大姨來幫忙。

3、拓撲圖

image

          根據之前文章中成功的經驗,簡單改造一下,中間一個Windows系統和一個Ubuntu系統承載着.Net Core程序,有人會問Windows那個咋不來個IIS啊,我要說的是.Net Core實行走出去的原則,基本脫離IIS,如果IIS上面想部署.Net Core程序的話,需要安裝同樣的應用程序,並且站點配置的應用程序池也要變成“無托管代碼”。

4、開發.Net Core程序使用Session

4-1、創建一個Web程序

          用Vs2017創建一個.Net Core的Web應用程序,且這個應用程序不包含身份驗證信息

image

image

         創建完如下

image

4-2、.Net Core調用Session

        .Net Core使用Session,需要引用相關Session的NuGet包,網上一查,發現.Net Core的官方Session組件類似一個中間件,並且官方支持Redis。

         注意:.Net Core的Mvc不能直接使用Session,如果你在程序里面寫了個HttpContext.Session就會出現如下錯誤:Session has not been configured for this application or request.

image

4-2-1、Microsoft.AspNetCore.Session

         .Net Core使用Session必須安裝Microsoft.AspNetCore.Session,他的NuGet包安裝如下圖:

image

4-2-2、修改Startup.cs讓Session可用

          在相應位置加入高亮代碼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數組,所以復雜實體需要轉化成Json存入Session中。

【Session 寫入方法】

HttpContext.Session.SetString("key", "strValue");

【Session 讀取方法】

HttpContext.Session.GetString("key")

5、Session存儲介質更換為Redis

5-1、首先配置Redis

詳細配置方式見:Session分布式共享 = Session + Redis + Nginx

redis-server redis.windows.conf

詳細配置方式見:Session分布式共享 = Session + Redis + Nginx

5-2、安裝Microsoft.Extensions.Caching.Redis.Core

       NuGet中搜索Microsoft.Extensions.Caching.Redis.Core並安裝,此NuGet包是對Caching的拓展,即可以更換Caching存儲介質

image

5-3、appsettings.json配置Redis連接字符串

       appsettings.json配置Redis連接字符串(相當於web.config里面配置appsetting節點),注意:添加位置要在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 數據庫連接字符串
                   option.Configuration = Configuration.GetConnectionString("RedisConnection");
                   //redis 實例名
                   option.InstanceName = "master";
              });
              services.AddSession();
           } 
         
 

         頁面運行HttpContext.Session.GetString("key"),然后用Redis管理工具RedisDesktopManager查詢Session是否入庫。

4

5-5、發布前指定IP和端口(重要) 

         如果你沒有看這個步驟,繼續下面發布步驟,等你發布時候,你會發現一個尷尬的問題,就是你用IP訪問不了你的網站,用localhost可以訪問,.Net Core默認是5000端口,端口占用也會讓你的網站訪問不了。

         只需要在Program.cs中添加高亮代碼即可,細心地人已經看到.UseUrls(new string[] { }) 傳入的是個數組,那么這里定義多個網站,當你執行時候dotnet命令時候,多個網站都會啟動。

image

 
public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                  //增加處,*號表示ip 
                  .UseUrls(new string[] { "http://*:7201" })
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }

6、.Net Core 發布

6-1、Windows安裝.Net Core發布環境[10.2.107.100]

         1)安裝Windows Server Hosting (x64 & x86),相當於IIS,注意安裝時候請聯網(好像是自動下載sdk,具體沒仔細研究)。

image

        2)輸入dotnet命令驗證,如果“報’dotnet’不是內部或者外部命令”請找到“C:\Program Files\dotnet”文件夾中的dotnet.exe,用cmd來調用dotnet.exe來運行,或者添加系統環境變量(window中cmd命令可以節省在編寫命令時候可以.exe,即命令dotnet就是dotnet.exe)

image

       【坑1】

         在win7下提示一下錯誤:Failed to load the dll from [C:\Program Files\dotnet\host\fxr\1.0.1\hostfxr.dll], HRESULT: 0x80070057

image

         解決方法:

         需要安裝補丁:KB2533623

        下載地址如下:

         https://support.microsoft.com/en-us/kb/2533623 

      【坑2】

         注意.net Core版本,本文主要是用的.net Core 1.1.1開發的,下面兩個截圖是版本按錯了出的錯誤信息

image

6-2、Ubuntu安裝.Net Core發布環境[10.2.107.46]

         Ubuntu安裝.Net Core官方寫的很詳細了,照着做即可,千萬別抵觸Linux系統,抵觸的話那就別用.Net Core了,如果不知道Ubuntu和Linux的關系的話請百度。

image

         最后驗證dotnet命令是否可以使用。

image

6-3、發布網站

       在項目上右鍵->發布…

image

image

       點擊發布按鈕,生成的文件如下(SessionTest為應用程序名)

image

        好了,有了這些文件,我們只需要把這些文件扔到服務器上就成了,但是怎么啟動呢?通過查詢,網上說只要用dotnet命令就成。繼續實踐…

        說明:我的項目叫做image生成了image這個為主要的dll,也是程序的入口。

        大家都知道.Net Core是跨平台的,不同系統的服務器環境配置好了,網上查詢說是使用dotnet命令啟動網站,那么可以推斷出幾個平台的dotnet命令是一樣的。

6-3-1、Windows啟動.Net Core網站[10.2.107.100:7201]

         啟動.Net Core網站的命令很簡單,安裝好發布環境的應用程序,C:\Program Files\dotnet目錄如下(如果dotnet命令不能用,可以直接調用dotnet.exe這個應用程序。)

image

         將生成好的網站復制到服務器上

image

 cmd命令找到PublishOutput

cd C:\PublishOutput

image

dotnet運行網站命令

dotnet SessionTest.dll

成功以后(之后再編譯運行,會提示下面截圖)

image

訪問http://10.2.107.100:7201/(如果一台機子有多個網卡多個IP,其他IP的7201端口也是個獨立網站)

image

 

6-3-2、Ubuntu啟動.Net Core網站[10.2.107.46:7201]

想辦法將發布的程序復制到Ubuntu上面去,我測試使用的VBox虛擬機。

具體方法傳送門:virtualbox中ubuntu和windows共享文件夾設置

dotnet SessionTest.dll

image

訪問http://10.2.107.46:7201/

image

7、Nginx配置

7-1、網站端口修改

        nginx.conf配置修改

image

        listen   80; 改成 listen   81; 因為一般都被80都被使用。

server {
        listen       81;
        ……
}

7-2、增加負載均衡

  nginx.conf中添加upstream節點

 
upstream Jq_one { 
      server 10.2.107.100:7201; 
       server 10.2.107.46:7201;
} 
server {
.....
}
 

 

7-3、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;
}
 

7-4、Nginx啟動命令

        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


 

      本以為做了上述准備和相關代碼編寫,就能夠實現Session共享了,結果我想的太簡單了,應用程序發布后並不能實現Session共享,難道分布式共享下Session需要特殊處理?.Net我是怎么實現的,它們的方法應該方法類似。我突然想到了MachineKey這個東西,之前在.Net版本分布式共享時候需要添加這個東西,評論也有人問我什么要加MachineKey。后來只能搜索.Net Core Machinekey關鍵詞,找到了以下幾篇文章做參考。

      搭建分布式 ASP.NET Core Web

      ASP.NET Core 數據保護(Data Protection)

      坎坷路:ASP.NET Core 1.0 Identity 身份驗證(中集)

      net core 1.0 實現負載多服務器單點登錄

      此問題屬於數據安全問題,微軟在開發.Net Core中延續了之前的設計,采用數據保護(Data Protection)方式對一些內部數據進行加密解密設計,如:Session、Cookie等(遠不止這些)。這樣可以保證數據的真實性、完整性、機密性、隔離性。數據安全必然離不開加解密算法,大家想一下之前.Net的WebFrom中的ViewState,它最終解析到Html頁面是個hidden標簽里面有一串很復雜的字符串,這個字符串是被數據保護(Data Protection)機制加密過的。Session也一樣,大家可以看看Session存到Redis中啥樣,見下圖:

image

       數據保護(Data Protection)有個特性是隔離性,大家可以想象一下,數據保護核心是加密解密,常見的加密方式有對稱加密和非對稱加密,上一篇做分布式共享時候,兩台機子拷貝了同樣的MahcineKey,那么他的內部加密猜測好像是對稱加密,MachineKey直譯中文為“機器鑰匙”在聯想隔離性,那么可以推斷出來不同機子密鑰是不同的,那么MachineKey的作用是統一不同機子的密鑰。(吐血中…….這個只是個猜測,詳細原理請參考專業文章)

1、提取.Net Core的MachineKey

        .Net Core的MachineKey存儲是以key-xxxx-xxxx-xxxx-xxxx.xml的形式存儲的,那如何提取這個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 數據庫連接字符串
                option.Configuration = Configuration.GetConnectionString("RedisConnection");

                //redis 實例名
                option.InstanceName = "master";
            });
            services.AddMvc();
        }
 

       查看D:\Xml里的xml文件

imageimage

 

2、重寫IXmlRepository接口固定Key

       在項目中添加CustomXmlRepository.cs類,其中keyContent中填寫key.xml內容,注意:里面的幾個時間(現在還不能確定expirationDate對項目是否有影響),有人問我KeyContent能否從文件里讀,回答是可以,但是ubuntu的文件路徑保准不是Windows的d:\之類的,需要使用Linux的寫法,所以干脆字符串來的快。

 
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 數據庫連接字符串
                option.Configuration = Configuration.GetConnectionString("RedisConnection");

                //redis 實例名
                option.InstanceName = "master";
            });

            services.AddMvc();

        }

五、實現效果演示


         演示效果說明

         本機127.0.0.1也為10.2.107.100,因為電腦性能有限,沒有弄windows虛擬機,只弄了10.2.107.46這台Linux虛擬機。

         MachineKey的這個實現思路也可以用到.Net Core的身份驗證上。

         UNC文件也可以實現Session共享方式

         原理就是Windows和Linux通過文件共享和掛載的方式Key.xml共享一個文件,但是總覺得有點怪怪的,共享文件會不會被別人惡意篡改,所以最后采用重寫的方式實現。

         對UNC方式感興趣的請看:搭建分布式 ASP.NET Core Web

 

 

5 六、后記&感悟


         希望通過本文,讓大家對網站的可用性中有個簡單認識,並了解到Session存入Redis中的優勢。本文介紹的網站可用性內容中的冰山一角,還有許多知識需要我們去學習和積累。

        .Net Core版本的Session分布式共享,讓我們對.Net Core有了初步了解,.Net Core的高性能、跨平台、開源,讓許多人改變了對.Net的看法,但是.Net Core在中國市場的路還有很長要走,我認為.Net Core並不是扭轉.Net語言在中國市場占有率的銀彈。真正的銀彈也許是我們這些天天寫程序的.Neter,即使是微軟大量宣傳.Net Core、成功案例漫天飛,我們不去學習、不去了解新知識,我們最終會被淘汰。語言只是工具,只有通過不斷學習和努力,將知識消化、吸收並最終分享給別人才會有最大的收獲,我們在十字路口迷茫之時,為何不去學習新的知識和方法提升自身的經驗和閱歷。我經常會跟別人說,工作前幾年最重要的不是知識,而是你做事的風格和為目標持之以恆的信念,俗話說“江山易改,本性難移”,如果不好的工作態度和方法變成了你的工作習慣,即使換了語言、換了工作甚至轉了行,都會對你的職業發展有很大影響。好的習慣一定要堅持,有些事堅持一天可以、堅持兩天可以、但是堅持三個月以上,卻變成了無法完成的任務,更別提幾年了,“不積跬步,無以至千里”,只有堅持每天去磨練自己才能有所成長,因為我知道我不是天才,需要后天的努力才能成長。

      “踏踏實實做人,認認真真做事”我堅信自己的努力,一定會有回報的,只是現在還沒有抓住機遇。最后,向那些奮斗在一線使用.Net Core開發的人員致敬。

        以上總結是我熬的味道濃郁的心靈雞湯01DAAF7A,可話說啥時候能改掉我工作外的拖延症啊01D99C38,這篇文章一直拖拖拖,論文一直拖拖拖,學英語拖拖拖,還有好多事要做可一直也是拖拖拖,悲劇啊01D9102F。。。突然發現鴨梨山大啊,壞習慣不好改啊!請大家引以為戒!當然別做工作狂,身體健康更重要,有時間多陪陪家里人。

        個人觀點,有可能因為知識和閱歷的原因,分析片面,請多諒解。

 

七、參考文章


         ASP.NET Core 使用 Redis 和 Protobuf 進行 Session 緩存

        .Net Core Session使用

        Asp.net Core 使用Redis存儲Session

        Using Sessions and HttpContext in ASP.NET Core and MVC Core

        .NET Core與.NET Framework、Mono之間的關系

        virtualbox中ubuntu和windows共享文件夾設置  

        搭建分布式 ASP.NET Core Web

        ASP.NET Core 數據保護(Data Protection)

        坎坷路:ASP.NET Core 1.0 Identity 身份驗證(中集)

        net core 1.0 實現負載多服務器單點登錄

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM