Azure Cache for Redis 6380端口连接出现SocketFailure异常
尝试使用SSL端口6380连接Azure Cache for Redis实例失败,但切换至非SSL端口6379可正常连接,相关代码及异常信息如下:
var configurationOptions = new ConfigurationOptions { EndPoints = { "***.redis.cache.windows.net:6380" }, Password = "*****=", Ssl = true, ConnectTimeout = 5000, SyncTimeout = 5000, IncludeDetailInExceptions = true, AbortOnConnectFail = false, }; // Use a custom IConnectionMultiplexer var connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions); // Add Redis to the services container with a custom IConnectionMultiplexer builder.Services.AddSingleton<IConnectionMultiplexer>(connectionMultiplexer); builder.Services.AddStackExchangeRedisCache(options => { options.ConfigurationOptions = configurationOptions; // Use the custom ConfigurationOptions }); var database = connectionMultiplexer?.GetDatabase(); // throws exception var value = await database!.StringGetAsync("key");
异常信息(中文翻译)
StackExchange.Redis.RedisConnectionException: 消息在等待发送的积压队列中超时,因为没有可用连接(超时时间1000ms)- 最后连接异常:my-redis.redis.cache.windows.net:6380/Interactive上发生SocketFailure,状态为Initializing/NotStarted,最近操作:NONE,来源:ConnectedAsync,未完成操作数:0,最近读取:0秒前,最近写入:0秒前,保活时间:60秒,连接状态:Connecting,连接管理器:10个可用连接中的10个,最近心跳:从未,全局心跳:0秒前,客户端版本:2.8.16.12844,命令:GET,超时:1000,实例:0,队列查询数:0,队列大小:0,异步等待:False,后台工作:CheckingForTimeout,读取状态:NotStarted,写入状态:Initializing,输入字节数:0,上次输入:0,当前输入:0,同步操作数:0,异步操作数:2,服务器端点:my-redis.redis.cache.windows.net:6380,连接时长:n/a,可用连接数:0,连接计数:1/1/0,连接管理器:10个可用连接中的10个,客户端名称:THIRU(SE.Redis-v2.8.16.12844),IOCP:(忙碌=0,空闲=1000,最小=1,最大=1000),WORKER:(忙碌=1,空闲=32766,最小=12,最大=32767),线程池:(线程数=7,排队任务数=0,已完成任务数=89,计时器数=2),客户端版本:2.8.16.12844
解决方法
- 指定TLS协议版本:Azure Redis要求使用TLS 1.2及以上,在配置中显式设置:
若客户端为离线环境,需手动导入Azure Redis信任的根证书。configurationOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls12; - 升级StackExchange.Redis版本:当前2.8.16版本存在SSL连接相关bug,通过NuGet升级到最新稳定版(如2.7.x及以上)。
- 调整超时参数:SSL握手耗时更长,增大连接和同步超时时间:
configurationOptions.ConnectTimeout = 10000; configurationOptions.SyncTimeout = 10000; - 排查网络限制:确认客户端网络允许访问6380端口,检查防火墙、代理是否拦截SSL流量,可通过telnet工具验证端口连通性。
- 延迟获取Database实例:等待连接就绪后再获取数据库,避免初始化阶段调用:
await connectionMultiplexer.WaitUntilConnectedAsync(); var database = connectionMultiplexer.GetDatabase(); - 验证Access Key完整性:确保Azure Redis的访问密钥(Password)复制完整,不要遗漏末尾的等号。
内容的提问来源于stack exchange,提问作者pingpong2020

