摘要: 近期的一个C++项目里使用了Zookeeper做服务发现,期间遇到了SessionTimeOut问题的困扰,明明通过zookeeper c client设置了超时时间,但无效。 请原谅我一开始对zookeeper不熟悉。

0.前言

本文为笃行日常工作记录,烂笔头系列。

源码前面,了无秘密 — by 侯杰

近期的一个C++项目里使用了Zookeeper做服务发现,期间遇到了SessionTimeOut问题的困扰,明明通过zookeeper c client设置了超时时间,但无效。

请原谅我一开始对zookeeper不熟悉。最终通过分析源码了解到SessionTimeOut最终的确定是一个协商的过程,而不是简单的配置生效。

在这里记录下Session超时时间的有关分析,基于zookeeper 3.4.8

1.zookeeper client SessionTimeOut

项目中使用的是 C client,通过zookeer_init 创建zk session,调用了zookeeper_init其实就开始了建立链接到ZK集群的过程,这里设置的recv_timeout 为客户端所期望的session超时时间,单位为毫秒。

ZOOAPI zhandle_t *zookeeper_init(const char *host, watcher_fn fn,int recv_timeout, const clientid_t *clientid, void *context, int flags);

连接成功之后客户端发起握手协议,可以看到之前设置的recv_timeout随握手协议一起发送给服务端,zookeeper.c#L1485。

static int prime_connection(zhandle_t *zh)
{int rc;/*this is the size of buffer to serialize req into*/char buffer_req[HANDSHAKE_REQ_SIZE];int len = sizeof(buffer_req);int hlen = 0;struct connect_req req;req.protocolVersion = 0;req.sessionId = zh->seen_rw_server_before ? zh->client_id.client_id : 0;req.passwd_len = sizeof(req.passwd);memcpy(req.passwd, zh->client_id.passwd, sizeof(zh->client_id.passwd));req.timeOut = zh->recv_timeout; <-这里设置timeOutreq.lastZxidSeen = zh->last_zxid;req.readOnly = zh->allow_read_only;hlen = htonl(len);/* We are running fast and loose here, but this string should fit in the initial buffer! */rc=zookeeper_send(zh->fd, &hlen, sizeof(len));serialize_prime_connect(&req, buffer_req);rc=rc<0 ? rc : zookeeper_send(zh->fd, buffer_req, len);if (rc<0) {return handle_socket_error_msg(zh, __LINE__, ZCONNECTIONLOSS,"failed to send a handshake packet: %s", strerror(errno));}

再来看看处理握手协议Resp的逻辑 zookeeper.c L1767

static int check_events(zhandle_t *zh, int events)
{if (zh->fd == -1)return ZINVALIDSTATE;………………deserialize_prime_response(&zh->primer_storage, zh->primer_buffer.buffer);/* We are processing the primer_buffer, so we need to finish* the connection handshake */oldid = zh->client_id.client_id;newid = zh->primer_storage.sessionId;if (oldid != 0 && oldid != newid) {zh->state = ZOO_EXPIRED_SESSION_STATE;errno = ESTALE;return handle_socket_error_msg(zh,__LINE__,ZSESSIONEXPIRED,"sessionId=%#llx has expired.",oldid);} else {zh->recv_timeout = zh->primer_storage.timeOut; //设置为Resp的Timeoutzh->client_id.client_id = newid;}

至此可以发现,最终客户端的SessionTimeOut时间实际是经过服务端下发之后的,并不一定是最先设置的。

2.Zookeeper Server SessionTimeOut

2.1协商客户端上报的SessionTimeOut

来看看服务端握手的处理逻辑ZooKeeperServer.java#L876。

public void processConnectRequest(ServerCnxn cnxn, ByteBuffer incomingBuffer) throws IOException {BinaryInputArchive bia = BinaryInputArchive.getArchive(new ByteBufferInputStream(incomingBuffer));ConnectRequest connReq = new ConnectRequest();connReq.deserialize(bia, "connect");
……
……
……//根据客户端上报的timeout和服务端自身的minSessionTimeOut。//如果上报的timeout小于minSessionTimeOut则 设置timeout为minSessionTimeOut.//如果上报的timeout大于maxSessionTimeOut则 设置timeout为maxSessionTimeOut.//如果介于两则之间,则以上报的时间为准。int sessionTimeout = connReq.getTimeOut();byte passwd[] = connReq.getPasswd();int minSessionTimeout = getMinSessionTimeout();if (sessionTimeout < minSessionTimeout) {sessionTimeout = minSessionTimeout;}int maxSessionTimeout = getMaxSessionTimeout();if (sessionTimeout > maxSessionTimeout) {sessionTimeout = maxSessionTimeout;}cnxn.setSessionTimeout(sessionTimeout);
……
……
……}

可以一句话概括,客户端上报的期望timeout一定要在服务端设置的上下界之间,如果越过边界,则以边界为准。

2.2 服务端MinSessionTimeOut和MaxSessionTimeOut的确定

转载于:https://my.oschina.net/u/3472227/blog/1186542

行杂记之Zookeeper SessionTimeOut分析相关推荐

  1. r语言error in match.fun(fun) :_Go语言200行写区块链源代码分析

    Github上有一个Repo,是一个使用Go语言(golang),不到200行代码写的区块链源代码,准确的说是174行.原作者起了个名字是 Code your own blockchain in le ...

  2. 《信息系统行锁等待的成因分析及智能化解决方案》

    " 我们都知道数据库锁等待危害巨大,直接后果是业务失效或业务缓慢.<信息系统行锁等待的成因分析及智能化解决方案>一文是由极简智能CTO黄之怡(中关村中联企业金融投资创新促进会首席 ...

  3. mysql影响行数解析_对PHP函数mysqli_affected_rows的作用行数返回值的分析

    这篇文章主要介绍了PHP中mysqli_affected_rows作用行数返回值,实例分析了普通模式与oop模式的用法,具有一定的参考借鉴价值,需要的朋友可以参考下 本文实例分析了PHP中mysqli ...

  4. 8位可控加减法器_行测高分技巧-资料分析之有效数字加减法取舍

    资料分析是我们行测试卷中得分率较高的一个部分,所以对资料分析这一部分的题目我们必须把握.但是做题过程中,考生碰到一些数字较大,列式复杂的题目,就无从下手,不知如何应对,今天陕西京佳教育就和各位考生聊一 ...

  5. 教你一招如何使用几行代码实现zookeeper作为springcloud的服务注册中心

    如果没有安装过zookeeper,请移步 zookeeper的单机安装 - 详细教程:https://blog.csdn.net/Kevinnsm/article/details/116134397 ...

  6. Zookeeper Listener分析

    KafkaController会通过zookeeper监控整个Kafka集群的运行状态,响应管理员的指令,通过在指定znode添加listener, 监听该znode的数据或者子节点等变化 一 Top ...

  7. Zookeeper原理分析之存储结构ZkDatabase

    ZKDatabase在内存中维护了zookeeper的sessions, datatree和commit logs集合. 当zookeeper server启动的时候会将txnlogs和snapsho ...

  8. SAP中MD04中交货计划行例外信息07的分析

    在MD04中经常可以看到如下图的计划行有例外信息07过去的结束日期.那么这个提示的含义是什么?会影响到什么?如何去解决呢?这就需要去检查交货计划的执行情况. 如下图事务ME38中,显示两笔交货计划,但 ...

  9. python用excel数据做热力图_7行代码 Python热力图可视化分析缺失数据处理-Python 实用宝典...

    Python热力图寻找缺失数据 你有没有遇到一种情况,处理一张很大的csv表格的时候很难找到表格中每一列的缺失数据,或者说处理速度非常慢 ?当然如果你的Excel水平非常高,这个可能不会成为你的问题, ...

  10. 鸿蒙内核代码 行,鸿蒙内核源码分析(CPU篇) | 内核是如何描述CPU的 ? | 祝新的一年牛气冲天 ! | v36.01...

    本篇说清楚CPU 读本篇之前建议先读鸿蒙内核源码分析(总目录)进程/线程篇.指令是稳定的,但指令序列是变化的,只有这样计算机才能够实现用计算来解决一切问题这个目标.计算是稳定的,但计算的数据是多变的, ...

最新文章

  1. 国产海翼号水下滑翔机首次应用于北极科考
  2. Ceilometer Polling Performance Improvement
  3. 九坤投资投身基础科研,携手IDEA成立联合实验室
  4. Elasticsearch 简介
  5. 直播 | AAAI 2021:自然语言中token-aware的虚拟对抗样本训练
  6. 即时通讯软件测试方法,Linux系统环境下如何使用aMsn即时通讯
  7. This is Me!——回顾第一个项目的前前后后
  8. Windows 7+Ubuntu 16.04 双系统安装
  9. mybatis 二级缓存使用注意
  10. laravel框架常用目录路径
  11. sicily 1002. Anti-prime Sequences
  12. 适合程序员的健身方法(转)
  13. 教孩子学编程 python 下载_教孩子学编程 python语言版
  14. VMware Workstation中的虚拟共享存储
  15. web开发中实现页面记忆的几种方式
  16. 原生JS中动态添加元素
  17. 关于JFreeChart中BarChart柱体宽度设置的问题纪要
  18. 2E07-view-lists-Collapsed
  19. 在Unity中通过NGUI UITexture制作动态聊天表情
  20. 使用 Fresco 实现大图浏览(支持手势放大、拖拽)

热门文章

  1. 微信“小程序”要来了,简单点,解释的方式简单点
  2. 计算机视觉之目标检测(object detection)《1》
  3. 电脑分区合并——灰色解决方法
  4. 理解IaaS、SaaS、paas的含义及区别
  5. eggs和egg是什么意思_egg是什么
  6. IDEA部署web项目时,Artifact中war和war exploded的区别
  7. VS与VS Code的区别
  8. 马克飞象自定义代码段风格
  9. Sara 老友记 第一季第六集 Joey天天演烂片
  10. 三数之和java实现ArrayList-leetcode算法编程-探索字节跳动面试