问题

带着问题撸源码系列-zookeeper-临时节点[ephemeral]是怎么弄的?我写了一堆临时节点为啥我一掉线就全没了?

猜测

可能是有线程维护着,每个session有一个临时节点列表,一旦客户端不再发心跳就全干掉

源码

我们可以看到,在DataTree里确实有以sessionid为key的这么个ConcurrentHashMap。

debug

run server 1(follower)
debug server 2 (leader)
client 请求server2: create -e /t1

我们可以直接出绝招,把断点打在创建临时节点的底层代码那里:
org.apache.zookeeper.server.DataTree#createNode(java.lang.String, byte[], java.util.List<org.apache.zookeeper.data.ACL>, long, int, long, long, org.apache.zookeeper.data.Stat)


然后我们请求就可以看到调用栈了:

一步到位,酸爽。我们可以从这里发现什么信息呢?

1、传入的ephemeralOwner是sessionid,=-1代表不是ephemeral节点
2、最终临时节点是写到ephemerals里的

然后我们看看是怎样做到客户端一掉线,临时节点就全没了的:

老办法,我们在deleteNode直接打断点,看是怎么触发的:


我们用客户端先

create -e /e1

然后

close

就触发了断点,轻松又愉快地找到了调用栈:

可以看到,实际上也是走的leader的职责链
相当于给leader发了一个closeSession的命令


最终就会走到deleteNode函数。

这的确最终是删除了/e1节点,不过从调用栈还是没有解决我们的问题,是谁发出的请求要删掉这个/e1节点呢?

鉴于所有给leader的请求都是走职责链的,所以我们从最开始的PrepRequestProcessor看是怎么处理close session的。

找着找着我们看到了org.apache.zookeeper.server.PrepRequestProcessor#pRequest2Txn

这里面就是把当前session里的ephemeral 节点找出来,每个加到record里,然后估计又会有地方消耗这个queue:

咱们的FinalRequestProcessor会来清空queue。每次Request都会走到FinalRequestProcessor所以肯定能处理到这个请求。

于是就回到咱们刚才那个调用栈了。

其实还有问题。如果不是主动关闭session,而是断线了呢?

我们在看代码的过程中可以看到有个session expiration thread

大概率就是跟这个有关系。我们可以找相关的代码瞅一瞅。
我们搜索下expriation 找到了这个:

按照注释,就是用这个ExpiryQueue来track的
按时间排序的,固定间隔的buckets。
什么鬼?
再仔细看看这个sessionExpiryQueue是个什么结构。

sessionExpiryQueue: 包含成员:
eleMap: ConcurrentHashMap key是SessionImpl,value是个时间
expiryMap: ConcurrentHashMap key是时间,value是个set,里面放了过期的SessionImpl。

SessionTrackerImpl有用到,那我们就去看看呗

有预感这里有一些奇妙的数据结构和算法。
看到这是一个线程,那就直接看他的run方法。(可以预计这是在某个初始化的时候启动了这个线程)

死循环在跑。每次从sessionExpiryQueue获取等待时间,如果还需要等,那就睡一会。否则从队列中哪一个出来。设置session关掉。

poll的时候,目的是要获取过期的session 列表。
获取当前时间,如果还没到点,就返回空列表。
如果到点了,那就设置一个下一次过期的时间,并把这一次过期的列表拿出来返回。

所以这个队列又是谁在往里放?

回答问题

看了这些,我们可以总结出整体思路。

1、每次session发心跳了,我们就更新一下这个数据结构。调用update方法,把当前session的过期时间更新一下。(这里细节是不能直接+interval,而是需要round一下,因为这个将作为key保存那些即将过期的session)

2、有一个线程不停地尝试从队列里poll,如果找到过期的session,那就查找出session对应的那些ephemeral,delete node。
poll的细节是,保存一个”下一次过期时间”nextExpirationTime。如果当前时间已经超过了nextExpirationTime那就以这个为key去拿出session set,这个session set就是过期的session列表。

带着问题撸源码系列-zookeeper-临时节点[ephemeral]是怎么弄的?我写了一堆临时节点为啥我一掉线就全没了?相关推荐

  1. 带着问题读源码-soul(2021-01-16)

    ### 带着问题读源码系列之Dubbo插件 像往常一样启动 [soul-admin] 和 [soul-bootstrap] . 因为dubbo需要依赖zookeeper, 需要需要启动一个监听在 lo ...

  2. 带着问题读源码-soul(2021-01-14)

    下载编译 git clone git@github.com:dromara/soul.gitcd soulmvn clean package install -Dmaven.test.skip=tru ...

  3. 带着问题读源码-soul(2021-01-15)

    带着问题读源码系列-soul的本地服务筛选 在上一期中,了解到soul的http请求是通过dividePlugin插件完成对本地服务的筛选. 总体来说,可以分为两步: 1. 选出符合调用要求的服务列表 ...

  4. 源码系列第1弹 | 带你快速攻略Kafka源码之旅入门篇

    大家过年好,我是 华仔, 又跟大家见面了. 从今天开始我将为大家奉上 Kafka 源码剖析系列文章,正式开启 「Kafka的源码之旅」,跟我一起来掌握 Kafka 源码核心架构设计思想吧. 今天这篇我 ...

  5. java 源码系列 - 带你读懂 Reference 和 ReferenceQueue

    java 源码系列 - 带你读懂 Reference 和 ReferenceQueue https://blog.csdn.net/gdutxiaoxu/article/details/8073858 ...

  6. 源码解读_入口开始解读Vue源码系列(二)——new Vue 的故事

    作者:muwoo 转发链接:https://github.com/muwoo/blogs/blob/master/src/Vue/2.md 目录 入口开始解读Vue源码系列(一)--造物创世 入口开始 ...

  7. c++ map 获取key列表_好未来Golang源码系列一:Map实现原理分析

    分享老师:学而思网校 郭雨田 一.map的结构与设计原理 golang中map是一个kv对集合.底层使用hash table,用链表来解决冲突 ,出现冲突时,不是每一个key都申请一个结构通过链表串起 ...

  8. 手把手带你阅读Mybatis源码(三)缓存篇

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 前言 大家好,这一篇文章是MyBatis系列的最后一篇文章,前面两篇文章:手把手带你阅读M ...

  9. 手把手教你如何导入源码,zookeeper为例

    要学习zookeeper,不可避免的一项就是zookeeper源码的导入工作.本次使用的idea. 步骤: 安装java就省略啦 手把手教你如何导入源码,zookeeper为例 软件 一,安装idea ...

最新文章

  1. Lodop 分页详解,可详细了呢
  2. Boost:bind绑定转发2个参数的测试
  3. 五个在线图形工具创建简单的设计元素
  4. C#垃圾回收机制(GC)
  5. python目前版本强势英雄_王者荣耀目前版本什么英雄强势?
  6. 写cookies注意事项
  7. 实现库函数strlen和strcpy
  8. linux云存储软件,推荐5个Linux云存储解决方案
  9. 同花顺 sendmessage python_进程通信-SendMessage使用方法
  10. CSS3 动画、变形效果
  11. opencv计算机视觉学习笔记一
  12. RQNOJ 能量项链
  13. 创意视频混音软件:Remixvideo for Mac
  14. 国内自动化测试软件,AutoRunner-国内测试行业专业自动化测试工具成长史
  15. 手把手带你写 Vue 可视化拖拽页面编辑器
  16. 第一性原理分子动力学(AIMD)结果分析教程
  17. CDN是什么?为何要用CDN加速网站?
  18. SparkStreaming的背压机制
  19. 2022年河北二级建造师建设工程施工管理《施工合同管理》练习及答案
  20. 支付宝社交风波以道歉收场,微信小程序会有不同结局吗?

热门文章

  1. web前端换行代码是什么?
  2. [RK3288] [Android 7.1] u-blox GPS调试
  3. 描绘用户场景并将典型用户和用户场景描述
  4. 翻译: Clustered Index Design Considerations 聚集索引设计注意事项
  5. 【微信小程序】全局样式文件app.wxss、页面的根元素page、 app.json中的window配置项
  6. unity 影子效果
  7. 导盲机器人 英语作文_中英文速记【中英文速记英语头条】- 中英文速记知识点 - 中企动力...
  8. tp5 实现文章上一篇和下一篇翻页
  9. 大智慧c语言编程,【图】大智慧外接DLL之C语言编程源码交流帖_数据、教程交流论坛_理想论坛 - 股票论坛...
  10. 使用modprobe加载驱动