首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

从Redis连接池获取连接失败的原因说起(5)

从Redis连接池获取连接失败的原因说起(5)

jedis客户端的socket设置

正在无解之际,突然想到是不是redis客户端设置了一些参数呢?
终于,在jedis控制连接的redis.clients.jedisConnection类中,找到了连接时对socket的设置:

    public void connect() {
        if (!isConnected()) {
          try {
            socket = new Socket();
            // ->@wjw_add
            socket.setReuseAddress(true);
            socket.setKeepAlive(true); // Will monitor the TCP connection is
            // valid
            socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
            // ensure timely delivery of data
            socket.setSoLinger(true, 0); // Control calls close () method,
            // the underlying socket is closed
            // immediately
            // <-@wjw_add
     
            socket.connect(new InetSocketAddress(host, port), connectionTimeout);
            socket.setSoTimeout(soTimeout);
     
            if (ssl) {
              if (null == sslSocketFactory) {
                sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
              }
              socket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, true);
              if (null != sslParameters) {
                ((SSLSocket) socket).setSSLParameters(sslParameters);
              }
              if ((null != hostnameVerifier) &&
                  (!hostnameVerifier.verify(host, ((SSLSocket) socket).getSession()))) {
                String message = String.format(
                    "The connection to '%s' failed ssl/tls hostname verification.", host);
                throw new JedisConnectionException(message);
              }
            }
     
            outputStream = new RedisOutputStream(socket.getOutputStream());
            inputStream = new RedisInputStream(socket.getInputStream());
          } catch (IOException ex) {
            broken = true;
            throw new JedisConnectionException("Failed connecting to host "
                + host + ":" + port, ex);
          }
        }
      }

这个socket.setSoLinger(true, 0);引起了我的注意。
根据SCTP rfc SO_LINGER的解释

    If the l_linger value is set to 0, calling close() is the same as the ABORT primitive.

继续看SCTP_ABORT:

    SCTP_ABORT: Setting this flag causes the specified association
    to abort by sending an ABORT message to the peer. The ABORT
    chunk will contain an error cause of 'User Initiated Abort'
    with cause code 12. The cause-specific information of this
    error cause is provided in msg_iov.

不太明白,看下TCP中对Abort的解释吧
TCP rfc对Abort的解释:

    This command causes all pending SENDs and RECEIVES to be
    aborted, the TCB to be removed, and a special RESET message to
    be sent to the TCP on the other side of the connection.
    Depending on the implementation, users may receive abort
    indications for each outstanding SEND or RECEIVE, or may simply
    receive an ABORT-acknowledgment.
    注:TCB是一个抽象的控制块(Transmission Control Block)
返回列表