首页 > 解决方案 > [vertx.redis.client]没有处理程序等待消息

问题描述

版本

vert.x 核心:3.5.0

vert.x redis 客户端:3.5.0

语境

2018-06-02 17:40:55.981 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:14751915

2018-06-02 17:41:10.937 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:假

2018-06-02 17:41:10.947 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:假

2018-06-02 17:41:20.937 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:true

2018-06-02 17:41:30.937 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:真

2018-06-02 17:41:35.927 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:假

2018-06-02 17:41:40.937 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:true

2018-06-02 17:41:50.948 错误 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection:没有处理程序等待消息:true

查看 io.vertx.redis.impl.RedisConnectioni 的代码后找到原因:

  1. 服务器启动后,创建redis连接,就可以运行了。

  2. 经过很长时间(例如几天)后,连接状态为 DISCONNECTED。Vert.x redis客户端在向redis服务器发送命令时重新连接redis服务器:

      无效发送(最终命令命令){

    // 如果没有连接就开始握手
    if (state.get() == State.DISCONNECTED) {
      连接();
    }

  1. connect() 调用 clearQueue()

  2. clearQueue():等待命令队列为空。

  3. 从具有新连接的 redis 服务器接收时调用 handleReply()。

注意:此处出现错误日志(倒数第三行)。

      私人无效句柄回复(回复回复){
        最终命令 cmd = waiting.poll();

        如果(cmd!= null){
          开关(回复。类型()){
            case '-': // 错误
              cmd.handle(Future.failedFuture(reply.asType(String.class)));
              返回;
            case '+': // 状态
              开关(cmd.responseTransform()){
                案例数组:
                  cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class))));
                  休息;
                默认:
                  cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
                  休息;
              }
              返回;
            case '$': // 批量
              开关(cmd.responseTransform()){
                案例数组:
                  cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class, cmd.encoding()))));
                  休息;
                案例信息:
                  字符串信息 = reply.asType(String.class, cmd.encoding());

                  如果(信息==空){
                    cmd.handle(Future.succeededFuture(null));
                  } 别的 {
                    字符串行[] = info.split("\\r?\\n");
                    JsonObject 值 = 新 JsonObject();

                    JsonObject 部分 = null;
                    对于(字符串行:行){
                      if (line.length() == 0) {
                        // 部分结束
                        部分=空;
                        继续;
                      }

                      if (line.charAt(0) == '#') {
                        // 开始部分
                        部分 = 新的 JsonObject();
                        // 创建一个带有节名的子键
                        value.put(line.substring(2).toLowerCase(), section);
                      } 别的 {
                        // 进入部分
                        int split = line.indexOf(':');
                        如果(部分==空){
                          value.put(line.substring(0, split), line.substring(split + 1));
                        } 别的 {
                          section.put(line.substring(0, split), line.substring(split + 1));
                        }
                      }
                    }
                    cmd.handle(Future.succeededFuture(值));
                  }
                  休息;
                默认:
                  cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType(), cmd.encoding())));
                  休息;
              }
              返回;
            case '*': // 多
              开关(cmd.responseTransform()){
                案例哈希:
                  cmd.handle(Future.succeededFuture(reply.asType(JsonObject.class, cmd.encoding())));
                  休息;
                默认:
                  cmd.handle(Future.succeededFuture(reply.asType(JsonArray.class, cmd.encoding())));
                  休息;
              }
              返回;
            case ':': // 整数
              开关(cmd.responseTransform()){
                案例数组:
                  cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(Long.class))));
                  休息;
                默认:
                  cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
                  休息;
              }
              返回;
            默认:
              cmd.handle(Future.failedFuture("未知消息类型"));
          }
        } 别的 {
          // **此处出现错误日志**
          log.error("没有处理程序等待消息:" + reply.asType(String.class));
        }
      }

问题:

这是一个错误还是不是?如果不是 bug ,重新连接 redis 服务器时 post 命令将被丢弃。

有什么好的方法来处理这种情况?

标签: redisvert.x

解决方案


问题已解决。出现上述问题的原因是连接被重用了,没有被关闭。解决办法是:`

RedisClient redisClient = RedisClient.create(this.vertx, redisOptions);
//do some thing; 
redisClient.close(h-{})...

` 对于每个会话。


推荐阅读