stackexchange.redis - 没有可用的连接来服务此操作(Redis 客户端)

标签 stackexchange.redis azure-app-service-envrmnt azure-redis-cache

我的应用程序托管在 azure 中,我正在使用 azure redis 缓存。

Redis客户端版本 Redis.StrongName - 1.2.6 .Net 核心 - 2.1 .Net框架4.7.1

我的应用程序出现间歇性 Redis 连接异常,一旦我重新启动应用程序服务,该异常就会得到解决。 我有 1 个辅助实例和 1 个主实例,其中 Redis 缓存容量为 6GB

这是我从客户那里得到的异常

外部消息: 没有可用的连接来服务此操作:HSETNX KEYNAME;我的 REDIS 服务器名称/交互式上的 SocketClosed,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,上次读取:0 秒前,上次写入:0 秒前,未应答写入:280531 秒前,保持事件:60 秒,待处理:0,状态:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s前,last-mbeat:0s前,global:0s前,mgr:非事件,err:从不; IOCP: (Busy=1,Free=999,Min=8,Max=1000), WORKER: (Busy=1,Free=32766,Min=8,Max=32767), 本地CPU: n/a

内部消息: 我的 REDIS 服务器名称/交互式上的 SocketClosed,来源:ProcessReadBytes,输入缓冲区:0,未完成:0,上次读取:0 秒前,上次写入:0 秒前,未应答写入:280531 秒前,保持事件:60 秒,待处理:0,状态:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s前,last-mbeat:0s前,global:0s前,mgr:非事件,err:从不

不确定出了什么问题,重新启动应用服务后问题就解决了。

请指导我 什么地方出了错? 如何调试Redis异常? 如何解释异常消息?

我提到了 stackexchange.Redis 中已经发布的一些问题,但没有提供有关此问题根本原因的良好信息 https://github.com/StackExchange/StackExchange.Redis/issues/559

我的 CPU 百分比和 Redis 服务器负载,看起来很好,没有异常

需要找出问题的根本原因

最佳答案

在 Azure 门户下,在 Redis 上执行任何操作时检查连接的客户端。就我而言,我发送了大约 4k 请求,但没有处理导致套接字失败的对象。实现 IDisposable 接口(interface)后,我能够毫无问题地处理 10k/20k 请求

  1. 更新您的连接字符串

    • 将 abortConnect 设置为 false
    • 根据需要调整您的syncTimeout 和asyncTimeout。
    • 如果您使用安全 TLS 连接,请在配置中设置 ssl=True,sslprotocols=tls12 以强制其使用最新版本。
  2. 如果可以的话,将 StackExchange.Redis nuget 包升级到最新版本。

  3. 将 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));
    
  4. 实现 IDisposable 以在使用后处置对象

         public void Dispose()
         {
             try {
                 if (connection.IsValueCreated)
                 {
                     connection.Value.Dispose(); 
                 }
             } catch { }
         }
    

关于stackexchange.redis - 没有可用的连接来服务此操作(Redis 客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57060636/

相关文章:

azure - 如何将 Azure SQL 托管实例连接到 Azure 应用服务(用 .NET Core 2.2 编写)

azure - 使用 azure 自动化脚本扩大和缩小 azure 应用服务计划(基于非工作时间)

azure - 将 Azure 网站中托管的 WebAPI 移动到 Visual Studio 2015 RC 中的 Azure API 应用程序

caching - Redis 缓存 - "Server Closed the connection"错误

c# - 使用 Azure Redis 缓存重试策略

c# - StackExchange Redis - StringSet 与 SetAdd 和过期

c# - 即使指定了 TimeSpan.MaxValue 过期,HashSet 也会从 Redis 缓存中删除

redis - AppFabric 缓存到 Redis - 等效于 GetAndLock 方法?

asp.net-core - StackExchange.Redis:如何配置 Redis 实例