[vertx.redis.client]没有处理程序在等待消息

时间:2018-06-05 09:58:10

标签: redis vert.x

版本

vert.x core:3.5.0

vert.x redis客户端:3.5.0

上下文

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

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

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

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

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

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

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

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

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

  1. 当服务器启动时,创建redis连接,它可以运行。

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

  3. 
          void send(final Command command) {
    
        // start the handshake if not connected
        if (state.get() == State.DISCONNECTED) {
          connect();
        }
    
    
    1. connect()调用clearQueue()

    2. clearQueue():wait command quene将为空。

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

    4. 注意:此处显示错误日志(第三行到底部)。

      
            private void handleReply(Reply reply) {
              final Command cmd = waiting.poll();
      
              if (cmd != null) {
                switch (reply.type()) {
                  case '-': // Error
                    cmd.handle(Future.failedFuture(reply.asType(String.class)));
                    return;
                  case '+':   // Status
                    switch (cmd.responseTransform()) {
                      case ARRAY:
                        cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class))));
                        break;
                      default:
                        cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
                        break;
                    }
                    return;
                  case '$':  // Bulk
                    switch (cmd.responseTransform()) {
                      case ARRAY:
                        cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class, cmd.encoding()))));
                        break;
                      case INFO:
                        String info = reply.asType(String.class, cmd.encoding());
      
                        if (info == null) {
                          cmd.handle(Future.succeededFuture(null));
                        } else {
                          String lines[] = info.split("\\r?\\n");
                          JsonObject value = new JsonObject();
      
                          JsonObject section = null;
                          for (String line : lines) {
                            if (line.length() == 0) {
                              // end of section
                              section = null;
                              continue;
                            }
      
                            if (line.charAt(0) == '#') {
                              // begin section
                              section = new JsonObject();
                              // create a sub key with the section name
                              value.put(line.substring(2).toLowerCase(), section);
                            } else {
                              // entry in section
                              int split = line.indexOf(':');
                              if (section == null) {
                                value.put(line.substring(0, split), line.substring(split + 1));
                              } else {
                                section.put(line.substring(0, split), line.substring(split + 1));
                              }
                            }
                          }
                          cmd.handle(Future.succeededFuture(value));
                        }
                        break;
                      default:
                        cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType(), cmd.encoding())));
                        break;
                    }
                    return;
                  case '*': // Multi
                    switch (cmd.responseTransform()) {
                      case HASH:
                        cmd.handle(Future.succeededFuture(reply.asType(JsonObject.class, cmd.encoding())));
                        break;
                      default:
                        cmd.handle(Future.succeededFuture(reply.asType(JsonArray.class, cmd.encoding())));
                        break;
                    }
                    return;
                  case ':':   // Integer
                    switch (cmd.responseTransform()) {
                      case ARRAY:
                        cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(Long.class))));
                        break;
                      default:
                        cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
                        break;
                    }
                    return;
                  default:
                    cmd.handle(Future.failedFuture("Unknown message type"));
                }
              } else {
                // **An error log appears here**
                log.error("No handler waiting for message: " + reply.asType(String.class));
              }
            }
      
      

      问题:

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

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

1 个答案:

答案 0 :(得分:0)

问题已经解决了。上述问题的原因是连接已被重用并且尚未关闭。解决方案是: `

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

` 为每个会话。