【问题标题】:No connection is available to service this operation (Redis Client )没有可用于服务此操作的连接(Redis 客户端)
【发布时间】:2019-11-25 09:20:51
【问题描述】:

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

RedisClient 版本 Redis.StrongName - 1.2.6 .Net 核心 - 2.1 .Net 框架 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 秒前,保持活动:60 秒,待处理:0,状态:ConnectedEstablished,in:0,ar:0,last-heartbeat:0s 前,last-mbeat:0s 前,全局:0s 前,mgr:不活动,err:从不

不知道是哪里出了问题,重启应用服务后就解决了。

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

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

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

需要找出问题的根本原因并

【问题讨论】:

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


    【解决方案1】:

    在 Azure 门户下检查连接的客户端,同时在 Redis 上执行任何操作。就我而言,我发送了大约 4k 的请求而没有处理导致套接字失败的对象。实现 IDisposable 接口后,我可以毫无问题地处理 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 { }
           }
      

    【讨论】:

      【解决方案2】:

      异常清楚地说明了发生了什么 - 有人关闭了您的套接字。这可能来自服务器端,因为它已超时(如果连接处于非活动状态,Azure redis 只会让它保持活动状态十分钟),或者因为服务器在故障转移期间必须暂时关闭连接,或者因为干预中的问题网络。

      但也有可能是由于您的应用程序中的错误导致套接字关闭,例如过早地处理连接。

      【讨论】:

        猜你喜欢
        • 2018-05-06
        • 2016-03-14
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-20
        • 2012-06-15
        • 2018-07-29
        相关资源
        最近更新 更多