概念
Zookeeper是一个分布式、可靠的、可扩展的协调服务,为分布式应用提供一致性服务。它是树型结构,能做到集群管理数据,当提供者出现断电等异常停机时,zk能自动删除提供者信息,当提供者重启时,能自动恢复注册数据。注意要在Dubbo消费者和提供者运行之前就启动zk服务。
基本配置
1、分别下载解压解压zookeeper-3.4.6,名字修改为zookeeper/zookeeper2/zookeeper3,下载时选择zookeeper-bin.tar.gz,不要选择另一个,否则启动报错(缺少jar包)
2、分别创建两个文件夹data和logs
3、data下分别创建myid,内容分别为为1,2,3
4、分别复制conf目录下的zoo.sample.cfg并命名为zoo.cfg,修改以下配置项
5、较新的版本中,需要zoo.cfg中设置admin端口
tickTime=2000 #zk的时间单元,zk的所有时间都以此为基准进行整数倍调整
initLimit=10 #Follower启动时从Leader同步最新数据,在10个tickTime后还没同步完,Leader会认为Follower连接失败
syncLimit=5 #Leader在5个tickTime还没收到Follower应答,则认为Follower已下线
dataDir=/usr/server/zookeeper2/data #通常和dataLogDir一起使用,存储快照文件
dataLogDir=/usr/server/zookeeper2/logs #存储事务日志
clientPort=2182 #zk的对外端口
server.1=zk01:2881:3881
server.2=zk02:2882:3882
server.3=zk03:2883:3883
# 注:server.A=B:C:D
A 是一个数字,表示节点编号,必须在dataDir目录下创建一个名为myid的文件,内容为该节点的编号;
B 是节点所在的ip地址
C 第一个端口是leader与follower之间进行心跳检测以及数据同步的端口;
D 是在 leader 选举时,用于投票通信的端口。
admin.serverPort=18080
真正的集群环境下,clientPort、C和D这几个端口是可以配置的完全一样的。当然也可以在本地搭建一个集群环境,只是需要使用不同的端口,它成为伪集群模式
zk集群配置
1、生产环境里,zk一般采用集群模式,ip端口用逗号隔开,dubbo-provider.xml如下配置
<dubbo:registry protocol="zookeeper" address="192.168.10.11:2181,192.168.10.12:2182,192.168.10.13:2183" />
2、管控台的dubbo.properties里配置
zookeeper://192.168.1.81:2181?backup=192.168.1.82:2182,192.168.1.83:2183
注:Zookeeper 集群中只要有过半的节点是正常的情况下,那么整个集群对外就是可用的。所以官方推荐zk安装2n+1台。
如果有四台挂掉两台,在有新的服务注册时,dubbo管控台重启就会挂掉,当重新启动某台zk,使其过半,管控台启动正常。
zk命令
zkServer.sh start/stop/status
jps //查看启动的进程
启动命令前先关闭防火墙,设置开机启动
systemctl stop firewalld
systemctl disable firewalld
修改rc.local来设置开机启动
cd /usr/server/backup/zookeeper2/ && ./zkServer.sh start
zk升级(单机-->集群)
1、先是在服务提供方,修改dubbo.registry.address=172.23.21.221:2181为
dubbo.registry.address=172.23.21.221:2181|172.23.21.222:2182,172.23.21.224:2184,172.23.21.224:2184
2、构建工程,然后修改消费者的配置,再去配置,此时会产生两套注册中心,
3、修改消费者的dubbo.registry.address=172.23.21.222:2182,172.23.21.224:2184,172.23.21.224:2184,去掉了221这台机器
4、构建消费者,最后同样的方法修改提供者的配置。
到相应的bin目录下,敲命令zkServer.sh status 会得到两种状态:follower或leader
zookeeper3.4.6配置实现自动清理日志
http://blog.csdn.net/reblue520/article/details/52311314
监控中心
统计服务的调用次数和调用时间的监控中心。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
监控中心需要修改的地方:dubbo.properties:
dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=monitor
dubbo.application.owner=
# 注册中心
dubbo.registry.address=zookeeper://192.168.1.81:2181?backup=192.168.1.82:2182,192.168.1.83:2183
dubbo.protocol.port=7373
dubbo.jetty.port=7272
# 监控数据存放地址
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${dubbo.jetty.directory}/charts
dubbo.statistics.directory=${dubbo.jetty.directory}/statistics
#日志
dubbo.log4j.file=/home/cxb/logs/dubbo-monitor/dubbo-monitor-simple.log
dubbo.log4j.level=WARN
【注】${user.home}指的就是启动dubbo-monitor程序的操作系统用户目录。我们这里用的是chang用户,那么就是/home/chang目录(如果是root用户启动,那就是/root)。
问题记录
一、 Zookeeper 集群节点为什么要部署成奇数?
这样是为了以最大容错服务器个数的条件下,能节省资源。
zookeeper集群有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。
2个zookeeper的死亡容忍度为0;3个zookeeper的容忍度为1;同理2->0; 3->1; 4->1; 5->2; 6->2 就会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,不必增加那一个不必要的zookeeper。
二、脑裂出现的场景
zookeeper过半机制中为什么是大于,而不是大于等于?目的就是为了防止脑裂。
对于Zookeeper来说有一个很重要的问题,就是到底是根据一个什么样的情况来判断一个节点死亡down掉了?在分布式系统中这些都是由监控者来判断的,但是监控者也很难判定其他的节点的状态,唯一一个可靠的途径就是心跳,Zookeeper也是使用心跳来判断客户端是否仍然活着。
假死:由于心跳超时(网络原因导致的)认为leader死了,但其实leader还存活着。
脑裂:由于假死会发起新的leader选举,选举出一个新的leader,但旧的leader网络又通了,导致出现了两个leader ,有的客户端连接到老的leader,而有的客户端则连接到新的leader。
es避免脑裂的方法相同,限定一个选举条件,设置Quorum(仲裁),只有master eligible节点数大于quorum时,才能进行选举
- quorum=(master节点总数/2)+1
- 当3个master eligible时,设置discovery.zen.minimum_master_nodes为2,即可避免脑裂
然而从7.0版本开始无需这个配置,让es自己选择可以形成仲裁的节点。