视频加载失败

记录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/
作者
小王的博客
发布于
2024-10-23
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
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` 命令,涵盖项目创建、构建、测试、部署等多个方面,助你提升开发效率!
随机文章随机推荐

评论区

Profile Image of the Author
小王的博客
一个上了年纪的猿人.
分类
标签
最新动态
站点统计
文章
209
分类
15
标签
161
总字数
478,322
运行时长
0
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录