自己搭建网站要钱吗,博达高校网站群建设教程,网页设计与制作怎么答辩,抖音代运营方案模板目录 前言阅读建议课程内容一、ZK Leader选举流程回顾二、源码流程图三、Leader选举模型图 学习总结 前言
为什么要看源码#xff1f;说实在博主之前看Spring源码之前没想过这个问题。因为我在看之前就曾听闻大佬们说过【JavaCoder三板斧#xff1a;Java#xff0c;Mysql说实在博主之前看Spring源码之前没想过这个问题。因为我在看之前就曾听闻大佬们说过【JavaCoder三板斧JavaMysqlSpring】所以我抱着积极的学习心态去看的。另外我也发现了一个很有意思的现象就是我们一群人在学习但是每个人学习的【偏好】似乎是不一样的或者说关注的重点不一样。所以其实我也不知道自己关注的重点到底对不对但总归是有收获的。 现在回过头来再看ZK源码有必要学习吗一开始我是觉得没必要的因为不少人说ZK源码写的很抽象、不规范但还是有人坚持说学习一下比较好。现在稍微学习了一小段之后我突然间有点感悟ZK源码还是值得学习阅读的甚至所有市面上以Java编写的分布式中间件都值得学习。为什么呢 首先ZK服务端是以Java编写出来的程序所以我们在阅读ZK源码的时候何尝不是一种进步呢咱可是直接在看行业大拿的源码啊 其次也可能是最重要的如果我们想成为一个优秀的JavaCoder甚至是架构师这确实是一条必经之路毕竟这些成熟、优秀的产品架构肯定能让你学到很多东西修炼内功 还有啊这些成熟、优秀的源码难道不值得学习吗这或许是世界上Java里面最牛逼的源码之一了 以上是我的一些思考。
同样这个问题我的老师也给出了他们的答案在这里分享给大家 Q1为什么要学习源码 答 提升技术功底学习源码里的优秀设计思想比如一些疑难问题的解决思路还有一些优秀的设计模式整体提升自己的技术功底深度掌握技术框架源码看多了对于一个新技术或框架的掌握速度会有大幅提升看下框架demo大致就能知道底层的实现技术框架更新再快也不怕快速定位线上问题遇到线上问题特别是框架源码里的问题(比如bug)能够快速定位这就是相比其他没看过源码的人的优势对面试大有裨益面试一线互联网公司对于框架技术一般都会问到源码级别的实现知其然知其所以然对技术有追求的人必做之事使用了一个好的框架很想知道底层是如何实现的拥抱开源社区参与到开源项目的研发结识更多大牛积累更多优质人脉 阅读建议
看源码方法
先使用先看官方文档快速掌握框架的基本使用抓主线找一个demo入手顺藤摸瓜快速静态看一遍框架的主线源码画出源码主流程图切勿一开始就陷入源码的细枝末节否则会把自己绕晕。实在看不懂的凭经验猜画图做笔记总结框架的一些核心功能点从这些功能点入手深入到源码的细节边看源码边画源码走向图并对关键源码的理解做笔记把源码里的闪光点都记录下来后续借鉴到工作项目中理解能力强的可以直接看静态源码也可以边看源码边debug源码执行过程观察一些关键变量的值整合总结所有功能点的源码都分析完后回到主流程图再梳理一遍争取把自己画的所有图都在脑袋里做一个整合
课程内容
我跟着老师看了一下源码说实在思考了很久实在不知道怎么给大家伙记下来分享给大家有点无从下手的感觉因为相关性太大了。所以这里算是自结吧主要是为了加深个人理解以及方便后续回头看。
一、ZK Leader选举流程回顾 我在之前的笔记当中有写过选举原理但是有点囫囵吞枣后来才知道原来这个挺重要的算是ZK比较重点的内容之一。现在这里重新讲解一番。
什么是Leader选举 ZooKeeper的Leader选举过程是基于投票和对比规则的确保集群中选出一个具有最高优先级的服务器作为Leader来处理客户端请求以及同步数据给集群中的其他节点。
选举规则 选举投票对比规则如下
首先比较epoch选取具有最大epoch的服务器。epoch用于区分不同的选举轮次每次重新选举时都会增加epoch。如果epoch相同则比较zxid事务ID选取事务ID最大的服务器。zxid表示最后一次提交的事务ID。如果zxid也相同则比较myid服务器ID选取服务器ID最大的服务器。 epoch表示ZooKeeper服务器的逻辑时期logical epoch它是一个相对时间的概念用于区分不同的Leader选举周期。 zxid是一个64位的整数由高32位的epoch和低32位的counter组成。 counter是一个在每个时期epoch内递增的计数器用于标识事务的顺序。 选举流程 首先得说明的是ZK的Leader选举是分两步的所以又叫两阶段选举。为什么需要两个阶段接下来我们看一下流程这个流程是我们网上能搜索到的大家都清楚的流程流程按照上面的模型图。即假设集群中有3个节点并且只启动了2个节点第3个节点没启动
ZK集群刚启动的时候由于他们仍未经历过选举所以每一台ZK机器中上面投票规则提到的epoch肯定是一样的包括zxid毕竟还没有接受过客户端的读写所以唯一的差异就在myId上了开始第一阶段选举由于彼此还不知道谁的epoch、zxid、myId所以会优先将票投给自己并且广播出去当然也能接收到别的服务器【投票自己的广播】。所以myid1的机器按照投票规则投票vote(1, 0)并且收到myid2的投票vote(2, 0)同时myid2的机器按照投票规则投票vote(2, 0)并且收到myid1的投票vote(1, 0)。显然目前投票情况是服务1跟服务2各收到一张选票所以Leader没办法选举出来第二阶段选举每个节点服务器收到投票广播后按照投票选举规则各自更新自己最新的投票。比如myid1的服务器经过比较之后发现myid2比自己更适合当Leader于是在第二轮投票的时候投票vote(2,0)而myid2的服务也经过比较之后觉得还是自己适合做Leader于是在第二轮投票的时候投票vote(2,0)。就这样myid2的服务收到了2张选票2 (3/2)符合【过半机制】于是成为了Leader接着myid3的节点上线发现已经有Leader了那不用投票了直接把自己置为Follower也许有人问为什么不重新选举因为没必要啊对于ZK集群来说尽快对外服务才是重点重新选举不是浪费时间嘛
OK流程回顾就到这里。相信大伙通过这个业务流程去理解代码将会事半功倍。
二、源码流程图
说明我估计很多人源码入口都找不到给大家一个方法也是很多源码阅读的办法。那就是从启动脚本找比如ZK我们知道它的启动脚本为zkServer.sh那就在里面找好了。
ZK源码入口类org.apache.zookeeper.server.quorum.QuorumPeerMain。 下面是是一个自结的源码流程图不是很好看。感兴趣的大伙可以跟着我的流程图看一遍源码 看完选举源码之后的一些总结与思考
【总结】比较清晰的了解为什么是二阶段选举因为ZK在设计投票与选举的时候是使用两个独立的业务领域类独立的线程来完成的投票决策领域类 投票发送/接受领域类也就是说他们的数据并非是直接耦合在一起的我描述的比较抽象咱也不知道该怎么解释了。【总结】在投票、选举中ZK新建了好几个业务线程往往是一个业务领域类本身就是一个线程子类然后在run方法中实现各自领域的逻辑。每个线程通常各自维护了一条阻塞队列线程之间交换数据是将消息发送至对应的阻塞队列中。也许这就是JVM级别不基于中间件的线程通信的可靠手段之一吧【思考】Leader节点与Follower节点节点之间投票都分别监听了独立的端口使用独立的scoket进行通信交互。其实前者Leader节点与Follower节点数据同步采用socket长连接保持通信我是能理解的但是选举方面我发现这个需求本来就不是特别大为什么也要用socket通信呢为什么不是http别笑我哈我一直以为socket比起http是一种比较重度的通信手段。现在看来可能跟我想象的不一样。sockert是传输层协议http是应用层协议且两者安全性方面前者更高。下面是来自gpt的回答 【总结】BIO网络连接在简单的应用通信之间还是很可靠的人家ZK都这么玩
三、Leader选举模型图
接下来再给大家画一下选举的相关模型图。 整个zookeeper选举底层可以分为【选举逻辑层】和【选举消息传输层】【逻辑层】有自己的队列统一接收和发送选票【传输层】也设计了自己的队列但是按发送的机器分了队列避免给每台机器发送消息时相互影响比如某台机器如果出问题发送不成功则不会影响对正常机器的消息发送。
学习总结
学习了ZK底层选举源码学习像JUC阻塞队列、网络通信在这种优秀应用中的使用思路学习了ZK源码设计思想。其实我看着很像是DDD的领域设计