依赖jar包版本注意
1,要下两个包,zookeeper的包和一个客户端包
2,zookeeper的包要和使用的zookeeper对齐
3,Curator包对应问题
Curator 2.x.x - compatible with both ZooKeeper 3.4.x and ZooKeeper 3.5.x
Curator 3.x.x - compatible only with ZooKeeper 3.5.x and includes support for new features such as dynamic reconfiguration, etc.
zk原理
1,开源的分布式协调服务,设计目标是将复杂且容易出错的分布式一致性服务封装成一个高效可靠的原语集,以提供用户简单易用的接口。
2,数据结点,znode,zk将所有数据结点存储在内存中,数据模型是一棵 znode 的树,每个结点不允许存储超过1M的数据
3,监听器watcher/listener,zk允许对节点的事件(增删改)进行监听,改变的时候zk服务器会通知有注册监听的客户端上去,通知只能是一个简单时间(通知状态,事件类型,节点路径),如果需要节点的具体变化,要重新访问zk
4,dubbo
/dubbo:dubbo在zk注册的根节点
/dubbo/com.foo.BarService:服务节点,代表了dubbo的一个服务
/dubbo/com.foo.BarService/Providers:服务提供者的根节点,其子节点代表了每个服务真正的提供者
/dubbo/com.foo.BarService/Consumers:服务消费者的根节点,其子节点代表了每个服务的真正消费者
dubbo工作流程:
服务提供者:在初始化的时候在/dubbo/com.foo.BarService/Providers创建一个子节点,同时写入自己的url地址,代表注册一个服务提供者
服务消费者:在初始化的时候订阅/dubbo/com.foo.BarService/Providers节点所有的子节点,并在Consumer字节创建自己的一个临时节点,作为一个消费者
zk服务中心:她需要知道一个服务的所有提供者和订阅者的变化情况,一旦提供者机器宕机该临时节点就会从zk上除去,这样服务消费者和监控中心都能感知到变化
5,分布式锁
利用zk强一致性的原理,多台机器在zk上创建一个节点,最终只有一台机器能创建成功节点,代表成功获得分布式锁
其他失败的节点添加监听,用完后删除节点,代表释放分布式锁,其他等待的客户端继续请求分布式锁
6,master选举
- zk本身根据zab协议进行的master选举,通过半数机器投票,快速选出有最新数据的zk master服务器
- 利用zk的一致性为其他客户端选举master
7,配置中心
- 将项目配置放到zookeeper集群中管理,配置节点内容在本地有缓存,内容更新后zk客户端将自动更新本地缓存,不需要重新打包、重启服务;
zk实战
1,框架初始化和zk的关系
- 在cat预加载的时候,预加载在/config/20078/clientRegistry/{project}上,这个应该不算注册的意思
- 在框架初始化上下文的时候初始化bean,读取了 common /clientIdInfo 这个节点,有一堆的 10001 -》ins -xxx-platform信息,不知道是干什么的
- 在框架初始化上下文的时候初始化bean,bean里面有调用工厂方法给一个静态服务赋值,在RPCFatory.getService(xxx.class)这个方法中激活了初始化他的静态模块,扫描依赖下的包,为她们注册RouterRPCHandle,到单例的RouterHelper,这个container会记录所有的服务,每个服务都有他的router,每个服务都通过条用zkclient的方法,为服务集群(config/pulibc/rpc/registry/${project})添加了监听,来实现动态的路由,从/rpc/config这个节点(这个节点的信息不知道怎么来的,估计是闪电后台根据注册信息获取,然后写上去的)获得rpc调用的基本配置信息,然后控制台输出一条:ins-router config: {health-check-mode=HTTP, health-check-interval=2000, udp-threshold=8, tcp-threshold=2, http-url=/monitor/http.do, http-threshold=3, multicast-ip=239.0.0.1, warmupPeriodSecond=20, permitsPerSecond=5, activeHeartbeatDelay=2000, heartbeatFailureCycle=15, routingTableCheckCycle=10, router={rule.enable=true, call.degrade.enable=true, call.degrade.group.enable=true, dynamicRouteGroup=[A, B, C], callDegradeRule={lpqa01=[lpqapub], lpqa02=[lpqapub], lpqa03=[lpqapub], lpqa04=[lpqapub], lpqa05=[lpqapub], lpqa06=[lpqapub], lpqapub=[lpqa01]}}} | RouterRegulation [ruleEnable=true, callDegradeEnable=true, callDegradeGroupEnable=true, dynamicRouteGroup=[A, B, C], callDegradeRule={lpqa01=[lpqapub], lpqa02=[lpqapub], lpqa03=[lpqapub], lpqa04=[lpqapub], lpqa05=[lpqapub], lpqa06=[lpqapub], lpqapub=[lpqa01]}] @ins-cv-platform new way! 这样的语句
- 最后在dispatchServlet的初始化中,把这个服务注册到,/config/pulibc/rpc/register/ins-xxx-platform/192.168.0.1上,添加listener,控制断线重连
2,listener模块,节点回调
listener回调分两种
- NodeChildListener : 子节点改变回调,一般用来跟新可用服务列表
- NodeListener : 监听节点改变回调,一般用来跟新配置
其他listener
- ConnectStateLIstener : 当前和zk的连接回调,一般用来短线重连
3,watch模块,节点监听
- NodeWatcher implements CuratorWatcher : 实现了curator的监听器,重写process方法,在节点上注册过监听的,将会成功收到节点的变化,根据增删改查的基本功能是1,更新缓存列表,2,重新注册监听,(因为只能用一次
- NodeEvenManager 节点事件管理类; 管理所有节点监听和客户端注册监听事件 。initListener方法是注册监听的入口。