做多服务器集群的时候,需要处理session。

一般两种处理方法,

第一,无session,就是不用session,不用session的话自然没有问题

第二,集中化session,所有session集中放在redis种。这样也没有问题

 

记录一下集中化session

首先引用包

Microsoft.AspNetCore.Session
Microsoft.Extensions.Caching.Redis.Core

 在startup中添加中间件

            services.AddDistributedRedisCache(option =>
            {
                //redis 数据库连接字符串
                option.Configuration = "192.168.1.132:6379";
                //redis 实例名
                option.InstanceName = "master";
            });
            services.AddSession();
            
            //添加使用
            app.UseSession();

这样就可以了。真是太方便了

 

【Session 写入方法】

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

【Session 读取方法】

HttpContext.Session.GetString("key")

 另外,页面上为了区分不同的server,这里取一下hostname

var hostname= Environment.GetEnvironmentVariable("COMPUTERNAME") ??Environment.GetEnvironmentVariable("HOSTNAME");

 

 

接下来,在docker中部署了5台app,1台nginx做负载均衡器,1台redis做session缓存。 记录下脚本

docker stop a1
docker stop a2
docker stop a3
docker stop a4
docker stop a5
docker rm a1
docker rm a2
docker rm a3
docker rm a4
docker rm a5
docker run --name a1 --restart=always -d -p 8001:80 -v /ocean/www:/wwwroot -w /wwwroot/ microsoft/aspnetcore dotnet /wwwroot/WebApplication1.dll
docker run --name a2 --restart=always -d -p 8002:80 -v /ocean/www:/wwwroot -w /wwwroot/ microsoft/aspnetcore dotnet /wwwroot/WebApplication1.dll
docker run --name a3 --restart=always -d -p 8003:80 -v /ocean/www:/wwwroot -w /wwwroot/ microsoft/aspnetcore dotnet /wwwroot/WebApplication1.dll
docker run --name a4 --restart=always -d -p 8004:80 -v /ocean/www:/wwwroot -w /wwwroot/ microsoft/aspnetcore dotnet /wwwroot/WebApplication1.dll
docker run --name a5 --restart=always -d -p 8005:80 -v /ocean/www:/wwwroot -w /wwwroot/ microsoft/aspnetcore dotnet /wwwroot/WebApplication1.dll

测试了一下,果然高兴的太早,试了一下,当server变化的时候,session不会同步。这是个问题,继续研究。

 

session其实是根据cookie的一个值来取的,而这个值得不同是因为.net core对其做了数据保护(data Protection) 

数据保护会调用机器自身的一个key值,该key值每台机器都不一样,因此最终造成cookie的值也不一样

 

为了解决这个问题。.Net Core团队提供了包将秘钥保存到redis中

添加包引用

Microsoft.AspNetCore.DataProtection.Redis

修改startup文件如下

            var redis = ConnectionMultiplexer.Connect("192.168.1.132:6379");
            services.AddDataProtection()
                .SetApplicationName("session_application_name")
                .PersistKeysToRedis(redis, "DataProtection-Keys");
            services.AddDistributedRedisCache(option =>
            {
                //redis 数据库连接字符串
                option.Configuration = "192.168.1.132:6379";
                //redis 实例名
                option.InstanceName = "master";
            });
            services.AddSession();

这次是真的OK了。哈哈哈

 

另外之前有写过一篇类似的 

http://blog.wx6.org/2017/929.htm



Leave a Reply