Board logo

标题: 从Redis连接池获取连接失败的原因说起(5) [打印本页]

作者: look_w    时间: 2019-2-20 19:04     标题: 从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)




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0