没有连接可用于为该操作提供服务(Redis 客户端)
No connection is available to service this operation (Redis Client )
我的应用托管在 azure 中,我使用的是 azure redis 缓存。
Redis客户端版本
Redis.StrongName - 1.2.6
.Net 核心 - 2.1
.Net Framework 4.7.1
我的应用出现间歇性 Redis 连接异常,并且在我重新启动应用服务后问题得到解决。
我有 1 个辅助实例和 1 个主实例,其中 Redis 缓存容量为 6GB
这是我从客户那里得到的例外情况
外部消息:
没有连接可用于服务此操作:HSETNX KEYNAME;我的 REDIS 服务器 NAME/Interactive 上的 SocketClosed,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,最后读取:0 秒前,最后写入:0 秒前,未答复写入:280531 秒前,保持活动状态: 60s,pending:0,state:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s 前,last-mbeat:0s 前,global:0s 前,mgr:Inactive,err:never; IOCP: (Busy=1,Free=999,Min=8,Max=1000), WORKER: (Busy=1,Free=32766,Min=8,Max=32767), Local-CPU: n/a
内心留言:
我的 REDIS 服务器 NAME/Interactive 上的 SocketClosed,来源: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 仅将其保持活动状态 10 分钟],或者因为服务器必须在故障转移期间暂时关闭连接,或者因为干预中的问题网络。
但也有可能是由于您的应用程序中的错误导致套接字被关闭,例如过早地处理连接。
在 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 { }
}
我的应用托管在 azure 中,我使用的是 azure redis 缓存。
Redis客户端版本 Redis.StrongName - 1.2.6 .Net 核心 - 2.1 .Net Framework 4.7.1
我的应用出现间歇性 Redis 连接异常,并且在我重新启动应用服务后问题得到解决。 我有 1 个辅助实例和 1 个主实例,其中 Redis 缓存容量为 6GB
这是我从客户那里得到的例外情况
外部消息: 没有连接可用于服务此操作:HSETNX KEYNAME;我的 REDIS 服务器 NAME/Interactive 上的 SocketClosed,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,最后读取:0 秒前,最后写入:0 秒前,未答复写入:280531 秒前,保持活动状态: 60s,pending:0,state:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s 前,last-mbeat:0s 前,global:0s 前,mgr:Inactive,err:never; IOCP: (Busy=1,Free=999,Min=8,Max=1000), WORKER: (Busy=1,Free=32766,Min=8,Max=32767), Local-CPU: n/a
内心留言: 我的 REDIS 服务器 NAME/Interactive 上的 SocketClosed,来源: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 仅将其保持活动状态 10 分钟],或者因为服务器必须在故障转移期间暂时关闭连接,或者因为干预中的问题网络。
但也有可能是由于您的应用程序中的错误导致套接字被关闭,例如过早地处理连接。
在 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 { } }