秒杀-StackExchangeRedisHelper连接单例

这个工具类的核心作用是提供一个线程安全的 Redis 连接单例,确保应用程序中始终使用同一个 ConnectionMultiplexer 实例操作 Redis,避免频繁创建连接带来的性能损耗。所有 Redis 操作都可通过该工具类获取连接,避免重复开发连接管理逻辑。

复制代码
using Infrastructure;
using StackExchange.Redis;
using System;
using System.Threading.Tasks;

namespace ZR.Infrastructure.Helper
{
    /// <summary>
    /// Redis 连接工具类,实现单例模式管理 ConnectionMultiplexer
    /// </summary>
    public static class StackExchangeRedisHelper
    {
        // 锁对象:保证多线程环境下创建连接的线程安全
        private static readonly object _lock = new object();

        // Redis 连接多路复用器(核心对象,代表与 Redis 服务器的连接)
        private static ConnectionMultiplexer _mux;

        /// <summary>
        /// Redis 连接字符串
        /// 从配置文件读取基础地址,并附加超时参数(连接超时 5 秒,同步操作超时 3 秒)
        /// </summary>
        private static string config = AppSettings.GetConfig("StackRedis:Redis") + ",connectTimeout=5000,syncTimeout=3000";

        /// <summary>
        /// 单例模式获取 ConnectionMultiplexer 实例
        /// 确保全局唯一连接,避免频繁创建连接的性能开销
        /// </summary>
        public static ConnectionMultiplexer Mux
        {
            get
            {
                // 双重校验锁:先判断连接是否有效,无效再进入锁逻辑(减少锁竞争)
                if (_mux == null || !_mux.IsConnected)
                {
                    // 加锁:保证同一时间只有一个线程执行连接创建逻辑
                    lock (_lock)
                    {
                        // 再次校验:防止多线程同时通过第一层判断后,重复创建连接
                        if (_mux == null || !_mux.IsConnected)
                        {
                            // 保存旧连接引用,避免直接释放导致正在使用的请求报错
                            var oldMux = _mux;

                            // 创建新的连接实例(根据配置字符串连接 Redis 服务器)
                            _mux = ConnectionMultiplexer.Connect(config);

                            // 延迟释放旧连接:给正在使用旧连接的请求留时间完成操作
                            if (oldMux != null)
                            {
                                // 异步延迟释放(不阻塞当前线程)
                                Task.Run(() =>
                                {
                                    try
                                    {
                                        // 等待 5 秒后释放旧连接(时间可根据业务调整)
                                        Task.Delay(5000).Wait();
                                        oldMux.Dispose();
                                    }
                                    catch { /* 忽略释放失败的异常,避免影响主流程 */ }
                                });
                            }
                        }
                    }
                }
                return _mux;
            }
        }

        /// <summary>
        /// 获取默认 Redis 数据库(0 号库)
        /// </summary>
        public static IDatabase Db => Mux.GetDatabase();

        /// <summary>
        /// 按需获取指定编号的 Redis 数据库
        /// </summary>
        /// <param name="db">数据库编号(默认 0 号库)</param>
        /// <returns>指定数据库的操作接口</returns>
        public static IDatabase GetDatabase(int db = 0) => Mux.GetDatabase(db);
    }
}
相关推荐
猿小羽1 分钟前
基于 Spring AI 与 Streamable HTTP 构建 MCP Server 实践
java·llm·spring ai·mcp·streamable http
大模型微调Online3 分钟前
深度复盘:Qwen3-4B-Instruct-2507微调实战——打造“快思考、强执行”的 ReAct IoT Agent
java·后端·struts
fie88893 分钟前
MATLAB中LASSO方法的特征矩阵优化与特征选择实现
开发语言·matlab·矩阵
铁蛋AI编程实战5 分钟前
Agentic AI/GPT-4o替代/Spring AI 2.0/国产大模型轻量化
java·人工智能·spring
筷乐老六喝旺仔6 分钟前
使用PyQt5创建现代化的桌面应用程序
jvm·数据库·python
weixin_704266056 分钟前
Maven入门:构建与依赖管理全解析
java·maven
cyforkk7 分钟前
14、Java 基础硬核复习:数据结构与集合源码的核心逻辑与面试考点
java·数据结构·面试
LilySesy8 分钟前
【SAP-MOM项目】二、接口对接(中)
开发语言·python·pandas·restful·sap·abap
零度@10 分钟前
专为 Java 开发者 整理的《Python编程:从入门到实践》前8章核心内容
java·开发语言·windows·python
一嘴一个橘子13 分钟前
idea Could not autowire. No beans of ‘xxxMapper‘ type found
java