赞
踩
前言
上篇文章我们学习了Zookeeper的选举流程和FastLeaderElection选举算法的实现过程,了解了Zookeeper从初始化开始到选举的过程,本篇文章我们开始研究Zookeeper中的会话机制体系
在Zookeeper中,会话是个很重要的概念之一,客户端与服务端之间的任何交互操作都和会话息息相关,其中包含zookeeper的临时节点的生命周期、客户端请求执行以及Watcher通知机制等。接下来,我们从全局的会话状态变化到创建会话再到会话管理三个方面来看看Zookeeper是如何处理会话相关的操作
客户端需要与服务端创建一个会话,这个时候客户端需要提供一个服务端地址列表,“ host1 : port,host2: port ,host3:port ” ,根据地址开始创建zookeeper对象,这个时候客户端的状态则变更为CONNECTION,同时客户端会根据上述的地址列表,按照顺序的方式获取IP来尝试建立网络连接,直到成功连接上服务器,这个时候客户端的状态就可以变更为CONNECTED。在zookeeper服务端提供服务的过程中,有可能遇到网络波动等原因,导致客户端与服务端断开了连接,这个时候客户端会进行重新连接操作,这个时候的状态为CONNECTION,当连接再次建立后,客户端的状态会再次更改为CONNECTED,也就是说只要在zookeeper运行期间,客户端的状态总是能保持在CONNECTION或者是CONNECTED。当然在建立连接的过程中,如果出现了连接超时、权限检查失败或者是在建立连接的过程中,我们主动退出连接操作,这个时候客户端的状态都会变成CLOSE状态。
Session是Zookeeper中会话的实例载体,一个Session则是指代一个客户端会话。一个会话必须包含以下几个基本的属性:
SessionID作为一个全局唯一的标识,我们可以来探究下Zookeeper是如何保证Session会话在集群环境下依然能保证全局唯一性的:
在sessionTracker初始化的时候,会调用initializeNextSession来生成session,算法大概如下:
public s ta tic long initializeNextSession(long id) {
long nextSid = 0;
nextSid = (System .currentTim eM illis() « 24) » 8;
nextSid = nextSid | (id « 5 6 );
return nextSid;
} }
从这段代码,我们可以看到session的创建大概分为以下几个步骤:
1.获取当前时间的毫秒表示
我们假设当前System.currentTimeMills()获取的值是1380895182327,其64位二进制表示为:
00000000 00000000 00000001 01000001 10000011 11000100 01001101 11110111
01000001 100000011 11000100 01001101 11110111 00000000 00000000 00000000,可以看到低位已经把高位补齐,剩下的低位都使用了0补齐
3.右移8位,结果变成了:
00000000 01000001 100000011 11000100 01001101 11110111 00000000 00000000
4.计算机器码标识ID:
在initializeNextSession方法中,出现了一个id变量,这个变量就是生成的SID的值,而SID在部署的时候就是我们在myid中配置的值,一般是一个整数,假设此时的值为2,转为64位二进制表示:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000010
此时发现高位几乎都是0,进行左移56位以后,得到值如下:
00000010 00000000 00000000 00000000 00000000 00000000 00000000 00000000
5.将前面第三步和第四步得到的结果进行 | 操作:
可以得到结果为:
00000010 01000001 10000011 11000100 01001101 11110111 00000000 00000000
这个时候我们可以得到一个单机中唯一的序列号ID,整个算法大概可以理解为,先通过高8位确定机器以后,后面的56位按照毫秒进行随机,可以看出来当前的算法!还是蛮严谨的,基本上看不出来什么明显的问题,但是其实也有问题的,其中我们可以看到,zk选择了当前机器时间内的毫秒作为基数,但是如果时间到了2022年4月8号以后, System . currentTimeMillis ()的值会是多少呢?
Date d = new Date (2022-1900 f 3,8);
System. out. p rin tln ( Long. toBinaryString(d .getTime()));
打印出来的结果为:
0000000000000000000000011000000000000100110000010000010000000000
接着我们左移24位以后会发现,这个时候的值依然是个负数,所以我们为了保证不会出现负数的情况,解决方案如下:
public static long initializeNextSession(long id { ) {
long nextSid = 0;
nextSid = (System .currentTim eM illis() « 24) > » 8;
nextSid = nextSid | (id « 5 6 );
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
第一章、 热修复设计
第一节、 AOT/JIT & dexopt 与 dex2oat
第二节、 热修复设计之 CLASS_ISPREVERIFIED 问题
第三节、热修复设计之热修复原理
第四节、Tinker 的集成与使用(自动补丁包生成)
第二章、 插件化框架设计
第一节、 Class 文件与 Dex 文件的结构解读
第二节、 Android 资源加载机制详解
第三节、 四大组件调用原理
第四节、 so 文件加载机制
第五节、 Android 系统服务实现原理
第三章、 组件化框架设计
第一节、阿里巴巴开源路由框——ARouter 原理分析
第二节、APT 编译时期自动生成代码&动态类加载
第三节、 Java SPI 机制
第四节、 AOP&IOC
第五节、 手写组件化架构
第四章、图片加载框架
第一节、图片加载框架选型
第二节、Glide 原理分析
第三节、手写图片加载框架实战
第五章、网络访问框架设计
第一节、网络通信必备基础
第二节、OkHttp 源码解读
第三节、Retrofit 源码解析
第六章、 RXJava 响应式编程框架设计
第一节、链式调用
第二节、 扩展的观察者模式
第三节、事件变换设计
第四节、Scheduler 线程控制
第七章、 IOC 架构设计
第一节、 依赖注入与控制反转
第二节、ButterKnife 原理上篇、中篇、下篇
第三节、Dagger 架构设计核心解密
第八章、 Android 架构组件 Jetpack
第一节、 LiveData 原理
第二节、 Navigation 如何解决 tabLayout 问题
第三节、 ViewModel 如何感知 View 生命周期及内核原理
第四节、 Room 架构方式方法
第五节、 dataBinding 为什么能够支持 MVVM
第六节、 WorkManager 内核揭秘
第七节、 Lifecycles 生命周期
本文包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
题集合/面经、及系列技术文章等,资源持续更新中…**
[外链图片转存中…(img-LbwWJksv-1712783321734)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-DhVtCrVs-1712783321734)]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。