Zookeeper + Dubbo大纲
Zookeeper
- zookeeper简介
- 核心概念
- CAP原则
- 一致性协议
- 2PC
- 3PC
- Paxox算法
- ZAB协议
- zookeeper环境搭建
- 单机环境
- zk集群搭配
- zookeeper基本使用
- zookeeper 数据结构
- zookeeper 命令行操作
- zookeeper API操作
- zookeeper源码解析
- zk启动过程
- watcher核心机制
- leader选举
- zookeeper应用场景
- 分布式配置中心
- 负载均衡
- 统一命名服务
- DNS服务
- 集群管理
- 分布式锁
- 分布式队列
Dubbo
-
RPC核心
-
常见的RPC框架
- dubbo
- 新浪微博开源motan
- facebook开源Thritf
- google开源gRPC
- 百度开源的bRPC
- Hessian
-
协议
- dubbo
- http
- RMI
- Hession
-
序列化
- JDK Serializable
- JSON序列化
- PST
- Thritf
- Hession
- Protacal Buffers
-
IO模型
- BIO:阻塞IO
- NIO:非阻塞IO
- Mutiplexing:IO多路复用
- AIO:异步IO
-
手写一套简单的RPC框架
-
-
dubbo高可用
- dubbo容错机制
- dubbo负载均衡策略与自定义实现
- dubbo服务降级
- 多版本控制
- 多注册中心
-
dubbo原理
- 协议
- 序列化
- 底层通信原理Netty
-
dubbo源码解析
- dubbo 的SPI
- dubbo 配置文件加载和解析
- provider 暴露服务
- consumer 消费服务
day01
1、分布式概述
早期我们使用单体架构,即所有服务部署在一台服务器的一个进展中,随着互联网的发展,逐步演进为分布式架构,多个服务分布部署在不同机器的不同进程中。
2、zookeeper概述
zookeeper是一个开源的分布式协调服务,提供分布式数据一致性解决方案,分布式应用程序可以实现数据发布订阅、负载均衡、命名服务、集群管理分布式锁、分布式队列等功能。
zookkeeper提供了分布式数据一致性解决方案,那什么是分布式数据一致性?首先我们谈谈什么叫一致性?
如图在上图中有用户user在DB1中修改balance=900,如果user下一次read请求到DB2数据,此时DB1的数据还没及时更新到DB2中,就会造成整个集群数据不一致。
数据一致性分为强一致性和最终一致性,强一致性指的如果数据不一致,就不对外提供数据服务,保证用户读取的数据始终是一致的,数据强一致性只需要通过锁机制即可解决,在案例中通过在DB2没有从DB1同步数据之前上锁,不对外提供读操作,只有当同步完成以后才对外提供服务。而最终一致性要求数据最终同步即可,没有实时性要求。
3、CAP原则
CAP在分布式系统中主要指的是一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)
-
一致性
- 一致性指的是强一致性
-
可用性
- 系统提供的服务一直处于可用状态,用户的操作请求在指定的响应时间内响应请求,超出时间范围,认为系统不可用
-
分区容错性
-
分布式系统在遇到任何网络分区故障的时候,仍需要能够保证对提供一致性和可用性服务,触发是整个网络都发生故障。
在一个分布式系统中不可能同时满足一致性、可用性、分区容错性,最多满足两个,对于分布式互联网应用而言,必须保证P,所有要么满足AP模型、要么满足CP模型
-
4、一致性协议
事务需要跨多个分布式节点时,为了保证事务的ACID特性,需要选举出一个协调者里协调分布式各个节点的调度,基于这个思维衍生了多种一致性协议:
(1) 2PC 而阶段提交
顾名思义,二阶段提交叫事务的提交过程分为两个阶段:
阶段一 提交事务请求
-
协调者向所有的参与者节点发送事务内容,询问是否可以执行事务操作,并等待其他参与者节点的反馈
-
各参与者节点执行事务操作
-
各参与者节点反馈给协调者,事务是否可以执行
阶段二 事务提交
根据一阶段各个参与者节点反馈的ack,如果所有参与者节点反馈ack,则执行事务提交,否则中断事务
- 事务提交:
- 协调者的各个参与者节点发送commit请求
- 参与者节点接受到commit请求后,执行事务的提交操作
- 各参与者节点完成事务提交后,向协调者返送提交commit成功确认消息
- 协调者接受各个参与者节点的ack后,完成事务commit
- 中断事务:
- 发送回滚请求
- 各个参与者节点回滚事务
- 反馈给协调者事务回滚结果
- 协调者接受各参与者节点ack后回滚事务
二阶段提交存在的问题:
- 同步阻塞
二阶段提交过程中,所有参与事务操作的节点处于同步阻塞状态,无法进行其他的操作
- 单点问题
一旦协调者出现单点故障,无法保证事务的一致性操作
- 脑裂导致数据不一致
如果分布式节点出现网络分区,某些参与者未收到commit提交命令,则出现部分参与者完成教程提交,未收到commit的命令的参与者则无法进行事务提交,整个分布式系统便出现了数据不一致性现象。
(2) 3PC 三阶段提交
3PC是2PC的改进版,实质是指2PC中提交事务请求拆分为两步,形成了CanCommit、PreCommit、doCommit三阶段的事务一致性协议
- 阶段一:CanCommit
- 事务询问
- 各参与者节点向协调者反馈事务询问的响应
- 阶段二:PreCommit
根据阶段一的反馈结果分为两种情况
-
执行事务预提交
- 发送预提交
协调者向所有参与者节点发送preCommit请求,进入prepared阶段
- 事务预提交
各参与者节点受到preCommit请求后,执行事务操作
- 各参与者节点向协调者反馈事务执行
2、中断事务
任意一个参与者节点反馈协调者响应No时,或者在等待超时后,协调者还未受到参与者的反馈,就中断事务,中断事务分为两步:
(1) 协调者向各个参与者节点发送abort请求
(2) 参与者受到abort请求,或者等待超时时间后,中断事务
- 阶段三:doCommit
1、执行提交
(1) 发送提交请求
协调者向所有参与者节点发送doCommit请求
(2) 事务提交
各参与者节点接受到doCommit请求后,执行事务提交操作
(3) 反馈事务提交结果
各参与者节点完成事务提交以后,向协调者发送ack
(4) 事务完成
协调者接受各个参与者反馈的ack后,完成事务
2、中断事务
(1) 参与者接受到abort请求后,执行事务回滚
(2) 参与者完成事务回滚以后,向协调者发送ack
(3) 协调者接受回滚ack后,回滚事务
3PC相较于2PC而言,解决了协调者挂点后参与无线阻塞和单点问题,但是仍然无法解决网络分区问题
(3) Paxos算法
Paxos算法是Leslie Lamport 1990年提出的一种一致性算法,该算法是一种提高分布式系统容错性的一致性算法,解决了3PC中网络分区的问题,paxos算法可以在节点失效、网络分区、网络延迟等各种异常情况下保证所有节点都处于同一状态,同时paxos算法引入了“过半”理念,即少数服从多数原则。
Paxos算法:基于消息传递且具有高度容错性的一种算法,是目前公认的解决分布式一致性问题最有效的算法
解决问题:在分布式系统中,如果产生宕机或者网络异常情况,快速的正确的在集群内部对某个数据的值达成一致,并且不管发生任何异常,都不会破坏整个系统的一致性
重要概念:半数原则:少数服从多数
paxos有三个版本:
- Basic Paxos
- Multi Paxos
- Fast Paxos
在paxos算法中,有四种种角色,分别具有三种不同的行为,但多数情况,一个进程可能同时充当多种角色/
- client:系统外部角色,请求发起者,不参与决策
- proposer:提案提议者
- acceptor:提案的表决者,即是否accept该提案,只有超过半数以上的acceptor接受了提案,该提案才被认为被“选定”
- learners:提案的学习者,当提案被选定后,其同步执行提案,不参与决策
Paxos算法分为两个阶段:prepare阶段、accept阶段
- prepare阶段
<1> proposer提出了一个提案,编号为N,发送给所有的acceptor。
<2> 每个表决者都保存自己的accept的最大提案编号maxN,当表决者收到prepare(N)请求时,会比较N于maxN的值,若N小于maxN,则提案已过时,拒绝preoare(N)请求。若N大于等于maxN则接收提案,并将该表决者曾经接收过的编号最大的提案Proposal(myid,maxN,value)反馈给提议者:其中myid表示表决者acceptor的标识id,maxN表示接受过的最大提案编号maxN,value表示提案内容。若当前表决未曾accept任何提议,会将proposal(myid,null,null)反馈给提议者。
- accept阶段
<1> 提议者proposal发出prepare(N)若收到超过半数表决者acceptor的反馈,proposal将真正的提案内容proposal(N,value)发送给所有表决者。
<2> 表决者acceptor接受提议者发送的proposal(N,value)提案后,会将自己曾经accept过的最大提案编号maxN和反馈的prepare的最大编号,若N大于这两个编号,则当前表决者accept该提案, 并反馈给提议者,否则拒绝该提议.
<3> 若提议者没有收到半数以上的表决者accept反馈,则重新进入prepare阶段,递增提案编号,重新提出prepare请求。若收到半数以上的accept,则其他未向提议者反馈的表决者称为learner,主动同步提议者的提案、
正常流程
单点故障,部分节点失败
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
proposer失败
Basic Paxos算法存在活锁问题(liveness)或dueling,而且较难实现
[
Multi Paxos:唯一的proposor,即leader
(4) ZAB协议(Fast Paxos)
由于paxos算法实现起来较难,存在活锁和全序问题(无法保证两次最终提交的顺序),所以zookeeper 并没有使用paxos作为一致性协议,而是使用了ZAB协议。
ZAB(zookeeper atomic broadcast):是一种支持奔溃恢复的原子广播协议,基于Fast paxos实现ZooKeeper使用单一主进程Leader用于处理客户端所有事务请求,即写请求。当服务器数据发生变更好,集群采用ZAB原子广播协议,以事务提交proposal的形式广播到所有的副本进程,每一个事务分配一个全局的递增的事务编号xid。
若客户端提交的请求为读请求时,则接受请求的节点直接根据自己保存的数据响应。若是写请求,且当前节点不是leader,那么该节点就会将请求转发给leader,leader会以提案的方式广播此写请求,如果超过半数的节点同意写请求,则该写请求就会提交。leader会通知所有的订阅者同步数据。
zookeeper第三种角色:
为了避免zk的单点问题,zk采用集群方式保证zk高可用
- leader
leader负责处理集群的写请求,并发起投票,只有超过半数的节点同意后才会提交该写请求
- follower
处理请求,响应结果,转发写请求到leader,在选举leader过程种参与投票
- observer
observer可以理解为没有投票权的follower,主要职责是协助follower处理读请求。那么当整个zk集群读请求负载很高时,为什么不增加follower节点呢?原因是增加follower节点会让leader在提出写请求提案时,需要半数以上的follower投票节点同样,这样会增加leader和follower的通信通信压力,降低写操作效率。
zookeeper两种模式
-
恢复模式
当服务启动或领导奔溃后,zk进入恢复状态,选举leader,leader选出后,将完成leader和其他机器的数据同步,当大多数server完成和leader的同步后,恢复模式接收
-
广播模式
一旦Leader已经和多数的Follower进行了状态同步后,进入广播模式。进入广播模式后,如果有新加入的服务器,会自动从leader中同步数据,leader在接收客户端请求后,会生成事务提案广播给其他机器,有超过半数以上的follower同意该提议后,再提交事务。
注意在ZAB的事务的二阶段提交中,移除了事务中断的逻辑,follower要么ack,要么放弃,leader无需等待所有的follower的ack。
zxid
zxid是64位长度的Long类型,其中高32位表示纪元epoch,低32位表示事务标识xid,即zxid由两部分构成:epoch和xid
每个leader都会具有不同的epoch值,表示一个纪元,每一个新的选举开启时都会生成一个新的epoch,新的leader产生,会更新所有的zkServer的zxid的epoch,xid是一个一次递增的事务编号,leader选举算法:
启动过程
- 每一个server发出一个投票给集群中其他节点
- 收到各个服务器的投票后,判断该投票有效性,比如是否是本轮投票,是否是looking状态
- 处理投票,pk别人的投票和自己的投票比较规则xid>myid”取大原则”
- 统计是否超过半数的接受相同的选票
- 确认leader,改变服务器状态
- 添加新server,leader已经选举出来,只能以follower身份加入集群中
奔溃恢复过程
- leader挂掉后,集群中其他follower会将状态从FOLLOWING变为LOOKING,重新进入leader选举
- 网上启动过程
消息广播算法:
一旦进入广播模式,集群中非leader节点接受到事务请求,首先会将事务请求转发给服务器,leader服务器为其生成对应的事务提案proposal,并发送给集群中其他节点,如果过半则事务提交;
- leader接受到消息后,消息通过全局唯一的64位自增事务id,zxid标识
- leader发送给follower的提案是有序的,leader会创建一个FIFO队列,将提案顺序写入队列中发送给follower
- follower接受到提案后,会比较提案zxid和本地事务日志最大的zxid,若提案zxid比本地事务id大,将提案记录到本地日志中,反馈ack给leader,否则拒绝
- leader接受到过半ack后,leader向所有的follower发送commit,通知每个follower执行本地事务
5、zookeeper环境搭建
zookeeper安装以linux环境为例,windows省略
(1) 单机环境
- 安装jdk
略…
-
zookeeper压缩包zookeeper-3.4.6.tar.gz上传到linux系统
Alt+P 进入SFTP,输入put d:\zookeeper-3.4.6.tar.gz 上传,d:\zookeeper-3.4.6.tar.gz是本地存放zookeeper的路径
-
解压缩压缩包
tar -zxvf zookeeper-3.4.6.tar.gz
- 进入zookeeper-3.4.13目录,创建data文件夹
cd conf
mv zoo_sample.cfg zoo.cfg
- 修改zoo.cfg中的data属性
dataDir=/root/zookeeper-3.4.6/data
- zookeeper服务启动
进入bin目录,启动服务输入命令
./zkServer.sh start
输出以下内容表示启动成功
(2) 集群环境
真实的集群是需要部署在不同的服务器上的,但是在我们测试时启动多个虚拟机的内存消耗太大,所以我们通常会搭建伪集群,也就是把所有的服务都搭建在一台虚拟机上,用端口进行区分。
准备工作
(1) 安装JDK 【此步骤省略】。
(2) Zookeeper压缩包上传到服务器
(3) 将Zookeeper解压到 /usr/local/zkcluster,创建data目录,将conf下zoo_sample_sample.cfg 复制三份文件并改名为 zoo1.cfg、zoo3.cfg
(4) 在解压后的Zookeeper目录下创建data目录,并分别创建三个子目录data1、data2、data3
/usr/local/zookeeper-cluster/zookeeper-1
/usr/local/zookeeper-cluster/zookeeper-2
/usr/local/zookeeper-cluster/zookeeper-3
[root@localhost]# mkdir /usr/local/zkcluster/data
[root@localhost]# cd data
[root@localhost]# mkdir data1
[root@localhost]# mkdir data2
[root@localhost]# mkdir data3
(5) 配置每一个Zookeeper 的dataDir (zoo.cfg) clientPort 分别为2181 2182 2183 修改 /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
clientPort=2181
dataDir-/usr/local/zookeeper-cluster/zookeeper-1/data
修改/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
clientPort=2182
dataDir=/usr/local/zookeeper-cluster/zookeeper-2/data
修/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg
clientPort=2183
dataDir=/usr/local/zookeeper-cluster/zookeeper-3/data
配置集群
(1) 在每个zookeeper的 data 目录下创建一个 myid 文件,内容分别是1、2、3.这个文件就是记录每个服务器的ID
(2) 在每一个zookeeper 的 zoo.cfg配置客户端访问端口 (clientPort) 和集群服务器IP列表。
server.1=192.168.25.129:2881:3881
server.2=192.168.25.129:2881:3882
server.3=192.168.25.129:2881:3883
server.服务器ID=服务器IP地址:服务器之间通信端口:服务器之间投票选举端口
启动集群
依次启动三个zk实例,其中有一个leader和两个follower
6、zookeeper基本使用
数据结构
Zookeeper数据模型的结果与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode,每个ZNode都可以通过其路径唯一标识
Znode节点类型
-
持久化目录节点(PERSISTENT)
客户端与zookeeper断开连接后,该节点依旧存在
-
持久化顺序编号目录节点(PERSOSTENT_SEQUENTIAL)
客户端zookeeper断开连接后,该节点依旧存,Zookeeper会给该节点按照顺序编号
-
临时目录节点(EPHEMERAL)
客户端与zookeeper断开连接后,该节点被删除
-
临时顺序编号目录节点(EPHEMERAL_SEQUENTIAL)
客户端与zookeeper断开连接后,该节点被删除,Zookeeper会给该节点按顺序编号
命令行使用
通过zkClient进入zookeeper客户端命令行,输入help查看zookeeper客户端的指令
如上图列出了zookeeper所有的客户端命令行,下图主要讲解常见的几个命令行
- 使用 ls 命令来查看当前znode中所包含的内容
ls path [watch]
- 查看当前节点数据并能看到更新次数等数据
ls path [watch]
- 创建节点 -s 含有序列 -e 临时
create
- 获得节点的值
get path [watch]
- 设置节点的值
set
- 查看节点状态
stat
- 删除节点
delete
7.递归删除节点
rm
api使用
maven依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.13</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
ZooKeeper zk = new ZooKeeper(String connectString, int sessionTimeout,Watcher watcher) | 创建zookeeper连接,connectString表示连接的zookeeper服务器的地址,sessionTimeOut指定会话的超时时间,Watchen配置监听 |
String create(String path,byte[] data, List aci,CreateMode createMode) | 创建一个给定的目录节点path,并给它设置数据,CreateMode 标识有四种形式的目录节点,分别是PERSISTENT:持久化目录节点,这个目录节点存储的数据不会丢失;PERSISTENT SEQUENTIAL:顺序自动编号的目录节点,这种目录接待你会根据当前已近存在的节点数自动加1,然后返回给客户端已经成功创建的目录节点名;EPHEMERAL:临时目录节点,一旦创建这个节点的客户端与服务器端口也就是session超时,这种节点会被自动删除;EPHEMEAL_SEQUENTIAL:临时自动编号节点 |
Stat exists(String path, boolean watch) | 判断某个 path 是否存在,并设置是否监控这个目录节点,这里的watcher 是创建 ZooKeeper 实例时指定的 watcher,exists方法还有一个重载方法,可以指定特定的watcher |
Stat exists(String path,Watcher watcher) | 重载方法,这里给某个目录节点设置特定的watcher,Watcher 在Zookeeper 是一个核心功能,Watcher 可以监控目录节点的数据变化以及子目录的变化,一旦这些状态发生变化,服务器就会通知所有设置在这个目录节点上的Watcher,从而每个客户端都很快知道它所关注的目录节点的状态发生变化,而做出相应的反应 |
void delete(String path, int version) | 删除path对呀的目录节点, version 为-1 可以匹配任何版本,也就删除了这个目录节点所有数据 |
ListgetChildren(String path, boolean watch) | 获取指定 path 下的所有子目录节点,同样 getChildren方法也有一个重载方法可以设置特定的watcher 监控子节点的状态 |
Stat setData(String path, bate[] data, int version) | 给 path 设置数据,可以指定这个数据的版本号,如果 version 为 -1 怎样可以匹配任何版本 |
byte[] getData(String path, boolean watch,Stat stat) | 获取这个 path 对应的目录节点存储的数据,数据的版本等信息可以通过stat来指定,同时还可以设置是否监控这个目录节点数据的状态 |
(2)启动
根据bin目录下的启动脚本zkServer.sh中加载启动类QuorumPeerMain类
QuorumPeerMain中main方法执行initializeAndRun方法
跟进initialzeAndRun方法
在initializeAndRun方法中主要做了三件事
- 加载解析配置文件
将配置文件加载到Properties.cfg对象中。解析cfg对象。zookeeper所有配置信息封装到一个QuorumPeerConfig对象中
- 启动定时清除任务
PurgeTask继承TimeTask,定时执行run方法中的purge方法
purge方法主要清除旧的快照和日志文件
-
启动zk
zookeeper启动方式分为两种:单机启动和集群启动
首先我们看看单机启动的源码main方法调用initializeAndRun方法,initializeAndRun首先加载配置文件,然后执行runFromConfig(config)方法,我们看看runFromConfig具体执行了什么操作
2、zookeeper应用场景
配置中心
在平常的业务开发过程中,我们通常需要将系统的一些通用的全局配置,例如及其列表配置,运行时开关配置,数据库配置信息等统一集中存储,让集群所有机器共享配置信息,系统在启动会首先从配置中心读取配置信息,进行初始化,传统的实现方法将配置存储在本地文件和内存中,一旦机器规模更大,配置变更频繁情况下,本地文件和内存方式的配置维护成本较高,使用zookeeper作为分布式的配置中心就可以解决这个问题。
我们将配置信息存在zk中的一个节点中,同时给该节点注册一个数据节点变更的watcher监听,一旦节点数据发生变更,所有的订阅该节点的客户端都可以获取数据变更通知。
负载均衡
建立server节点,并建立监听器监视servers子节点的状态(用于在服务器增添时及时同步当前集群中服务器列表),在每个服务器启动时,在servers节点下建立具体服务器地址的子节点并在对应的字节点下存入服务器的相关信息,这样,我们在zookeeper服务器上可以获取当前集群中的服务器列表及相关信息,可以自定义一个负载均衡算法,在每个请求过来时从zookeeper服务器中获取当前集群服务器列表,根据算法选出其中一个服务器处理请求。
命名服务
命名服务是分布式系统中的基本功能之一,被命名的实体通常可以是集群中的机器、提供的服务地址或者远程对象,这些都可以称作为名字。常见的就是一些分布式服务框架(RPC、RMI)中的服务地址列表,通过使用名称服务客户端可以获取资源的实体、服务地址和提供者信息,命名服务就是通过一个资源引用的方式来实现对资源的定位和使用,在分布式环境中,上层应用仅仅需要一个全局唯一名称,就像数据库中的主键。
在单库单表系统中可以通过自增ID来标识每一条记录,但是随着规模变大分库分表很常见,那么自增ID有仅能针对单一表生成ID,所以在这种情况下无法依靠这个标识唯一ID。UUID就是一种全局唯一标识符,但是长度过长不易识别。
- 在Zookeeper中通过创建顺序节点就可以实现,所有客户端都会根据自己的任务类型来创建一个顺序节点,例如job-000000001
- 节点创建完毕后,create()接口会返回一个完整的节点名,例如:job-00000002
- 拼接type类型和完整节点名作为全局唯一的ID
DNS服务
- 域名配置
在分布式系统应用中,每一个应用都需要分配一个域名,日常开发中,往往使用本地HOST绑定域名解析,开发阶段可以随时修改域名和IP的映射,大大提高开发的测试效率。如果应用的机器规模达到一定程度后,需要频繁更新域名时,需要在规模的集群中变更,无法保证实时性。所有我们在zk上创建一个节点来进行域名配置
- 域名解析
应用解析时,首先从zk域名节点获取域名映射的IP和端口。
- 域名变更
每个应用都会在在对应的域名节点注册一个数据变更的watcher监听,一旦监听的域名节点数据变更zk会向所有订阅的客户端发送域名变更通知。
集群管理
随着分布式系统日益扩大,集群中机器的数量越来越多。有效的集群管理越来越重要了,zookeeper集群管理主要利用了watcher机制和创建临时节点来实现,以机器上下线和机器监控为例:
- 机器上下线
新增机器的时候,将Agent部署到新增的机器上,当Agent部署启动时,会向zookeeper指定的节点创建一个临时子节点,当Agent在zk上创建临时节点,当关注的节点zookeeper/machines下的节点新加入新的节点时或删除都会发送通知,这样就对机器的上下线进行监控。
- 机器监控
在机器运行过程中,Agent会定时将主机的运行状态信息写入到/machines/hostn主机节点,监控中心通过订阅这些节点的数据变化来获取主机的运行信息。
分布式锁
-
数据库实现分布式锁
首先我们创建一张锁表,锁表中字段设置唯一约束
模达到一定程度后,需要频繁更新域名时,需要在规模的集群中变更,无法保证实时性。所有我们在zk上创建一个节点来进行域名配置
- 域名解析
应用解析时,首先从zk域名节点获取域名映射的IP和端口。
- 域名变更
每个应用都会在在对应的域名节点注册一个数据变更的watcher监听,一旦监听的域名节点数据变更zk会向所有订阅的客户端发送域名变更通知。
集群管理
随着分布式系统日益扩大,集群中机器的数量越来越多。有效的集群管理越来越重要了,zookeeper集群管理主要利用了watcher机制和创建临时节点来实现,以机器上下线和机器监控为例:
- 机器上下线
新增机器的时候,将Agent部署到新增的机器上,当Agent部署启动时,会向zookeeper指定的节点创建一个临时子节点,当Agent在zk上创建临时节点,当关注的节点zookeeper/machines下的节点新加入新的节点时或删除都会发送通知,这样就对机器的上下线进行监控。
- 机器监控
在机器运行过程中,Agent会定时将主机的运行状态信息写入到/machines/hostn主机节点,监控中心通过订阅这些节点的数据变化来获取主机的运行信息。
分布式锁
-
数据库实现分布式锁
首先我们创建一张锁表,锁表中字段设置唯一约束