zk negotiated timeout和响应timeout讨论

本文分析了在 ZooKeeper 客户端配置了特定超时时间后仍出现超时错误的原因。通过代码跟踪发现实际的读取超时时间与配置的会话超时时间有关,并非直接使用配置值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://crazyjvm.iteye.com/blog/1701032

http://crazyjvm.iteye.com/blog/1693757 文中提到相关超时问题,但是又出现了一个问题,我把min和max都设置成了180000,但是仍然出现了以下的异常信息:

Java代码   收藏代码
  1. Client session timed out, have not heard from server in 154339ms for sessionid 0x13a3f7732340003 ...  
  2. Client session timed out, have not heard from server in 167805ms for sessionid 0x13a3f7732340000 ...  

 

 

我们循着这个异常定位到:ClientCnxn.java

又看到zk存在如下信息:

Java代码   收藏代码
  1. Established session 0x13a3f773235011b with negotiated timeout 180000 for client /x.x.x.x:49702  

这说明我们的配置的确起效果了。那为何还会超时呢,下面几段代码可能会解答这个问题:

异常信息在这里抛出:

Java代码   收藏代码
  1. if (to <= 0) {  
  2.     throw new SessionTimeoutException(  
  3.            "Client session timed out, have not heard from server in "  
  4.              + idleRecv + "ms"  
  5.              + " for sessionid 0x"  
  6.              + Long.toHexString(sessionId));  
  7. }  

 而这段代码在:

Java代码   收藏代码
  1.  /** 
  2.      * This class services the outgoing request queue and generates the heart 
  3.      * beats. It also spawns the ReadThread. 
  4.      */  
  5. class SendThread extends Thread {  
  6.    //....  
  7. }  

 我们可以看到这个类负责维护发信息并且维护心跳,接着往下看这个类中的关键代码,

Java代码   收藏代码
  1. readTimeout = negotiatedSessionTimeout * 2 / 3;  //我们设置了180s, 那这个值就是120s  
  2. connectTimeout = negotiatedSessionTimeout / serverAddrs.size();  

 

Java代码   收藏代码
  1. long now = System.currentTimeMillis();  
  2.        long lastHeard = now;  
  3.        long lastSend = now;  
  4.        while (zooKeeper.state.isAlive()) {  
  5.             try {  
  6.                    if (sockKey == null) {  
  7.                        // don't re-establish connection if we are closing  
  8.                        if (closing) {  
  9.                            break;  
  10.                        }  
  11.                        startConnect();  
  12.                        lastSend = now;  
  13.                        lastHeard = now;  
  14.                    }  
  15.                    int idleRecv = (int) (now - lastHeard);  
  16.                    int idleSend = (int) (now - lastSend);  
  17.                    int to = readTimeout - idleRecv;  //答案就在这行,readTimeout,上面提到120s  
  18.                    if (zooKeeper.state != States.CONNECTED) {  
  19.                        to = connectTimeout - idleRecv;  
  20.                    }  
  21.                    if (to <= 0) {  
  22.                        throw new SessionTimeoutException(  
  23.                                "Client session timed out, have not heard from server in "  
  24.                                + idleRecv + "ms"  
  25.                                + " for sessionid 0x"  
  26.                                + Long.toHexString(sessionId));  
  27.                    }  
  28.            

假如我没有分析错的话,那么就是这个原因了。

此外lease和rpc也会可能超时,这个等下次再简单结合代码具体谈。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值