stackexchange.redis - 没有可用于服务此操作的连接(Redis 客户端)
问题描述
我的应用程序托管在 azure 中,我正在使用 azure redis 缓存。
RedisClient 版本 Redis.StrongName - 1.2.6 .Net Core - 2.1 .Net Framework 4.7.1
我的应用程序出现间歇性 Redis 连接异常,一旦我重新启动应用程序服务,它就会得到解决。我有 1 个辅助实例和 1 个主实例,其中 Redis 缓存容量为 6GB
这是我从客户那里得到的例外
外部消息:没有可用于服务此操作的连接:HSETNX KEYNAME;SocketClosed on MY REDIS SERVER NAME/Interactive,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,上次读取:0 秒前,上次写入:0 秒前,未回答写入:280531 秒前,保持活动:60 秒,待定:0,状态:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s前,last-mbeat:0s前,全局:0s前,mgr:不活动,err:从不;IOCP: (Busy=1,Free=999,Min=8,Max=1000), WORKER: (Busy=1,Free=32766,Min=8,Max=32767), Local-CPU: n/a
内部消息:SocketClosed on MY REDIS SERVER NAME/Interactive,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,最后读取:0 秒前,最后写入:0 秒前,未回答写入:280531 秒前,保持活动状态: 60s, pending: 0, state: ConnectedEstablished, in: 0, ar: 0, last-heartbeat: 0s ago, last-mbeat: 0s ago, global: 0s ago, mgr: Inactive, err: never
不知道出了什么问题,一旦我重新启动应用程序服务就解决了。
请指导我出了什么问题?如何调试 Redis 异常?如何解释异常消息?
我在 stackexchange.Redis 中提到了一些已经发布的问题,但没有提供有关此问题根本原因的良好信息 https://github.com/StackExchange/StackExchange.Redis/issues/559
我的 CPU 百分比和 Redis 服务器负载,看起来很好,没有异常
需要找出问题的根本原因
解决方案
在 Azure 门户下,在对 Redis 执行任何操作时检查连接的客户端。就我而言,我发送了大约 4k 的请求而没有处理导致套接字失败的对象。实现 IDisposable 接口后,我可以毫无问题地处理 10k/20k 请求
更新您的连接字符串
- 将 abortConnect 设置为 false
- 根据需要调整您的 syncTimeout 和 asyncTimeout。
- 如果您使用的是安全 TLS 连接,请在配置中设置 ssl=True,sslprotocols=tls12 以将其强制为最新版本。
如果可以,将您的 StackExchange.Redis nuget 包升级到最新版本。
在 C# 代码中将 ReconnectRetryPolicy 的配置选项设置为 ExponentialRetry https://stackexchange.github.io/StackExchange.Redis/Configuration.html#reconnectretrypolicy
private static readonly Lazy<ConfigurationOptions> configOptions = new Lazy<ConfigurationOptions>(() => { var connections = ConfigurationManager.ConnectionStrings["redis-connection"].ConnectionString; var configOptions = ConfigurationOptions.Parse(connections); configOptions.ClientName = "MyApp-RedisCacheProvider"; //configOptions.SyncTimeout = 100000; // don`t do this in code, set it in your connection string //configOptions.AbortOnConnectFail = false; // don`t do this in code, set it in your connection string /* * The default is LinearRetry which can cause congestion at virtually the same time on multiple parallel threads. * Use ExponentialRetry so that a degree of randomness is used in the timing across multiple threads. */ configOptions.ReconnectRetryPolicy = new ExponentialRetry(5000, 10000); return configOptions; }); private static readonly Lazy<ConnectionMultiplexer> connection = new Lazy<ConnectionMultiplexer>( () => ConnectionMultiplexer.Connect(configOptions.Value));
实现 IDisposable 以在对象使用后对其进行处置
public void Dispose() { try { if (connection.IsValueCreated) { connection.Value.Dispose(); } } catch { } }
推荐阅读
- vba - 如何在访问中编辑使用“更新后”选项创建的宏
- r - 闪亮未检测到输出中的输入
- html - CSS :hover 抽搐
- simple-injector - 使用非泛型接口装饰类,其中装饰器依赖于接口,而不是类
- haskell - 在 Haskell 中为命令式语言编写解释器
- julia - Julia“没有方法匹配 supports_default_copy_to(::GLPK.Optimizer, ::Bool)”声明模型
- javascript - 将按钮插入 Popover 不起作用
- excel - Excel 64 位返回“找不到文件:UKRM_EncodeEIB_D.dll.dll”
- c - 如何在 C 中编写代码来检查字符串中的重复单词并计算它们的出现次数?
- javascript - 将输入文本连接到滑块