记录Dotnet6中使用Redis共享Session的实现
785 字
4 分钟
记录Dotnet6中使用Redis共享Session的实现
前言
因项目中实际需要,需要对dotnet服务做横向扩展,但是Session默认存储在MemoryCache中,无法实现多台服务器共享Session,导致通过nginx做负载均衡后出现跳登录的情况,因此需要使用Redis共享Session解决此问题。
实现
安装依赖
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis 6.0.35
- Microsoft.Extensions.Caching.StackExchangeRedis 6.0.35
修改startup.cs/Program.cs
public void ConfigureServices(IServiceCollection services) { // ... 其他中间件 services.AddHttpContextAccessor(); services.AddMvc().AddSessionStateTempDataProvider();
services.AddHttpClient(); // 注入Session services.AddSessionService("CacheProvider"); // 使用Redis作为系统缓存 services.AddCacheService("CacheProvider"); services.AddControllersWithViews(ConfigureMvcOptions) .AddNewtonsoftJson(options => { options.UseMemberCasing(); // 格式化时间 options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; }); // ... 其他中间件 }services.AddSessionService(“CacheProvider”) 的实现方法
public static void AddSessionService(this IServiceCollection services, string key) { using (ServiceProvider provider = services.BuildServiceProvider()) { IConfiguration configuration = provider.GetRequiredService<IConfiguration>(); if (configuration == null) { throw new ArgumentNullException(nameof(IConfiguration)); } IConfigurationSection section = configuration.GetSection(key); if (!section.Exists()) { Console.WriteLine($"appsetting.json 文件中不存在 '{key}' 配置项,如需使用redis缓存,请增加此配置。将使用系统缓存。"); } CacheOptions options = section.Get<CacheOptions>(); if (options == null) { Console.WriteLine($"读取appsetting.json中'{key}'配置项失败,请正确配置。将使用系统缓存"); }
if (options?.CacheType == CacheTypeEnum.Redis.ToString()) { Console.WriteLine($"将使用Redis缓存Session信息");
var connStr = options.RedisConnectionString; var dic = connStr.Contains(',') && !connStr.Contains(';') ? connStr.SplitAsDictionary("=", ",", true) : connStr.SplitAsDictionary("=", ";", true);
var Server = dic["Server"]?.Trim(); var UserName = dic["UserName"]?.Trim(); var Password = dic["Password"]?.Trim();
#region 配置说明
// var options = new ConfigurationOptions // { // AbortOnConnectFail = false, // 连接失败时是否中止 // AllowAdmin = false, // 是否允许使用管理命令 // ConnectTimeout = 5000, // 连接超时时间(毫秒) // SyncTimeout = 5000, // 同步操作超时时间(毫秒) // ResponseTimeout = 5000, // 响应超时时间(毫秒) // ReconnectRetryPolicy = new LinearRetry(1000), // 重连策略 // DefaultDatabase = 0, // 默认数据库索引 // EndPoints = { "localhost:6379" }, // Redis节点的地址和端口 // Ssl = false, // 是否使用SSL加密连接 // SslHost = "localhost", // SSL连接时的主机名验证 // Password = "yourpassword", // Redis认证密码 // ClientName = "MyClient", // 客户端名称 // KeepAlive = 1800000 // 保持连接间隔时间(毫秒) // }; #endregion
//获取Redis 连接字符串 ConfigurationOptions redisConfigOption = new ConfigurationOptions(); redisConfigOption.EndPoints.Add(Server); redisConfigOption.AllowAdmin = false; redisConfigOption.Password = Password; redisConfigOption.ConnectTimeout = 60000; redisConfigOption.ResponseTimeout = 60000; redisConfigOption.SyncTimeout = 60000; redisConfigOption.ReconnectRetryPolicy = new LinearRetry(1000);// 重连策略 var redis = ConnectionMultiplexer.Connect(redisConfigOption);//建立Redis 连接
//添加数据保护服务,设置统一应用程序名称,并指定使用Reids存储私钥 services.AddDataProtection() .SetApplicationName("YZ") .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
//添加Redis缓存用于分布式Session services.AddStackExchangeRedisCache(options => { options.ConfigurationOptions = redisConfigOption; options.InstanceName = "YZ"; }); } //添加Session services.AddSession(options => { options.Cookie.Name = "YZ"; options.IdleTimeout = TimeSpan.FromMinutes(60 * 60); //设置session的过期时间 options.Cookie.HttpOnly = true; //设置在浏览器不能通过js获得该cookie的值 options.Cookie.IsEssential = true; });
} }services.AddCacheService(“CacheProvider”); 实现方法
/// <summary> /// 缓存注册(新生命Redis组件) /// </summary> /// <param name="services"></param> public static void AddCacheService(this IServiceCollection services, string key) { using (ServiceProvider provider = services.BuildServiceProvider()) { ICache cache = NewLife.Caching.Cache.Default;
IConfiguration configuration = provider.GetRequiredService<IConfiguration>(); if (configuration == null) { throw new ArgumentNullException(nameof(IConfiguration)); } IConfigurationSection section = configuration.GetSection(key); if (!section.Exists()) { Console.WriteLine($"appsetting.json 文件中不存在 '{key}' 配置项,如需使用redis缓存,请增加此配置。将使用系统缓存。"); } CacheOptions options = section.Get<CacheOptions>(); if (options == null) { Console.WriteLine($"读取appsetting.json中'{key}'配置项失败,请正确配置。将使用系统缓存"); }
if (options?.CacheType == CacheTypeEnum.Redis.ToString()) { Console.WriteLine($"将使用Redis缓存"); var redis = new FullRedis(); redis.Init(options.RedisConnectionString); cache = redis;
}
services.AddSingleton(cache); } }按照以上的配置,就可以实现使用redis共享Session了。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
记录Dotnet6中使用Redis共享Session的实现
https://blog.huhaha.vip/posts/7b05deaf/相关文章智能推荐
1
dotnet9中的认证鉴权学习
DotNetdotnet9中的认证鉴权学习
2
集群环境下,你不得不注意的ASP.NET Core Data Protection 机制
DotNet在集群环境中使用ASP.NET Core时遇到的数据保护问题。在单个容器中正常运行的Web应用,在扩展到多个容器后出现的会话信息丢失问题,并分析了其根本原因在于每个容器生成的私钥不同。提供了使用Redis作为存储介质来实现私钥共享的具体步骤,包括添加必要的NuGet包和配置数据保护服务及分布式Session的方法
3
效率提升利器,一个全龄段友好的DotNET万能工具库
DotNet介绍了Masuit.Tools库,这是一个适用于所有水平开发者的C#/.NET工具库。描述了该库的功能,包括加密解密、反射操作、树结构、文件探测、权重随机筛选算法、分布式短ID生成、表达式树、LINQ扩展、文件压缩、多线程下载、硬件信息获取、字符串扩展方法、日期时间操作、中国农历、大文件拷贝、图像裁剪等功能
4
Visual Studio 修改NuGet 包缓存路径
DotNetVisual Studio 下载的NuGet包默认会缓存到 C:\Users{Windows用户名}.nuget\packages 下,时间一长就会导致 C盘空间严重不足。 那么怎样去设置,让包缓存文件保存到其他盘呢?
5
.NET 开发者必备:全面整理常用 dotnet 命令
DotNet作为 .NET 开发者,你是否经常需要查找命令行指令?本文为你整理了开发过程中最常用的 `dotnet` 命令,涵盖项目创建、构建、测试、部署等多个方面,助你提升开发效率!
随机文章随机推荐
小王的博客














