使用StackExchange.Redis在C#中连接Azure Redis缓存超时问题
Azure Redis缓存集成.Net系统TLS 1.2代码配置问题
我正在将Azure Redis缓存(开发用Basic C0实例)集成到.Net 4.6.1系统中,使用StackExchange.Redis v2.6.90客户端库,运行环境均为Windows(本地Win10开发,测试用Server 2019 Std)。
编写的连接封装类
using System; using System.Net; using StackExchange.Redis; namespace Rimes.Azure { public class RedisCache { private ConnectionMultiplexer _redis; private void Initialize(ConfigurationOptions options) { // Azure requires TLS 1.2 but .Net uses TLS 1.1 by default ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; _redis = ConnectionMultiplexer.Connect(options); } public RedisCache(string endPoint, string token, bool useSsl = true, bool abortOnConnectFail = true) { var options = ConfigurationOptions.Parse(endPoint); options.Password = token; options.Ssl = useSsl; options.AbortOnConnectFail = abortOnConnectFail; Initialize(options); } public string Get(string key) { IDatabase db = _redis.GetDatabase(); return db.StringGet(key); } public bool Set(string key, string value, int timeToLive) { IDatabase db = _redis.GetDatabase(); return db.StringSet(key, value, TimeSpan.FromSeconds(timeToLive)); } } }
问题现象
代码在本地开发机器上运行正常,但测试服务器上完全无法工作,实例化、获取、设置操作均触发RedisTimeoutException错误,错误日志如下:
Exception type: RedisTimeoutException Exception message: Timeout performing PSETEX (5000ms), inst: 0, qu: 1, qs: 0, aw: False, bw: SpinningDown, last-in: 0, cur-in: 0, sync-ops: 2, async-ops: 1, serverEndpoint: xxx.redis.cache.windows.net:6380, conn-sec: n/a, mc: 1/1/0, mgr: 10 of 10 available, clientName: xxx(SE.Redis-v2.6.90.64945), IOCP: (Busy=0,Free=1000,Min=12,Max=1000), WORKER: (Busy=2,Free=32765,Min=12,Max=32767), v: 2.6.90.64945 at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server, T defaultValue) at Rimes.Azure.RedisCache.Set(String key, String value, TimeSpan expiry)
已尝试的排查步骤
- 将超时时间从默认5000ms提升至30000ms - 无变化
- 使用psping验证与Azure的连接 - 连接成功
- 检查本地服务器及Azure防火墙设置 - Azure无防火墙配置,本地服务器允许出站连接
- 检查.Net版本 - 两者均运行.Net 4.8,仅本地版本为4.8.04084,服务器版本为4.8.03761
- 联系网络团队排查外部因素 - 未发现异常
- 使用Python redis 3.5.3库重新开发 - 两台机器均能正常连接缓存
更新记录
更新1:
测试服务器在2月14日(周五)可正常运行,2月17日(周一)失效。发现微软在14日发布了两个.Net安全更新KB5022504和KB5022782,但卸载后问题仍存在。进一步发现服务器仅接收安全更新,本地开发机仅接收功能更新。
更新2:
开启并使用Azure Redis的非SSL端口可正常工作,回退到TLS 1.0也可正常工作,但设置更高版本TLS则失败,附加日志如下:
11:09:02.9964: Allowing 1 endpoint(s) 00:00:05 to respond... 11:09:02.9964: Awaiting 1 available task completion(s) for 5000ms, IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=4,Free=32763,Min=10,Max=32767) 11:09:03.0241: Configuring TLS 11:09:03.0554: Connection failed: xxx.redis.cache.windows.net:6380 (Subscription, AuthenticationFailure): AuthenticationFailure on xxx.redis.cache.windows.net:6380/Subscription, Initializing/NotStarted, last: NONE, origin: ConnectedAsync, outstanding: 0, last-read: 0s ago, last-write: 0s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 0s ago, v: 2.6.96.30123 11:09:03.0554: > A call to SSPI failed, see inner exception. 11:09:03.0554: > The function requested is not supported 11:09:03.0554: xxx.redis.cache.windows.net:6380: OnConnectedAsync completed (Disconnected) ... 11:09:03.1178: Endpoint Summary: 11:09:03.1178: xxx.redis.cache.windows.net:6380: Standalone v4.0.0, primary; keep-alive: 00:01:00; int: Disconnected; sub: Disconnected; not in use: DidNotRespond 11:09:03.1178: xxx.redis.cache.windows.net:6380: int ops=0, qu=0, qs=0, qc=0, wr=0, socks=3; sub ops=0, qu=0, qs=0, qc=0, wr=0, socks=3 11:09:03.1178: xxx.redis.cache.windows.net:6380: Circular op-count snapshot; int: 0 (0.00 ops/s; spans 10s); sub: 0 (0.00 ops/s; spans 10s) 11:09:03.1178: Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago 11:09:03.1178: Starting heartbeat... 11:09:08.1781: Encountered exception: StackExchange.Redis.RedisTimeoutException: The timeout was reached before the message could be written to the output buffer, and it was not sent, command=SUBSCRIBE, timeout: 5000, inst: 0, qu: 0, qs: 0, aw: False, bw: CheckingForTimeout, rs: NotStarted, ws: Initializing, in: 0, last-in: 0, cur-in: 0, sync-ops: 0, async-ops: 1, serverEndpoint: xxx.redis.cache.windows.net:6380, conn-sec: n/a, mc: 1/1/0, mgr: 10 of 10 available, clientName: LDOKTATEST01(SE.Redis-v2.6.96.30123), IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=6,Free=32761,Min=10,Max=32767), v: 2.6.96.30123 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebugge
基于配置TLS后的SSPI失败错误,移除了SecurityProtocol设置并通过注册表配置.Net使用TLS 1.2后问题解决。
当前需求
需要了解如何在代码中设置TLS 1.2版本,无需修改注册表即可正常工作。
内容的提问来源于stack exchange,提问作者Simon Pratt
相关产品推荐
相关产品推荐

