在设计监控方案前,我们先看一下如何来获取监控数据。
获取ZK监控数据的手段有两种:
第一种:使用ZK四字母命令
ZK提供了多达十几种四个字母的命令,用于获取ZK的状态信息。常见命令如下:
| 命令 | 功能 |
| conf | 打印服务配置信息 |
cons | 获取与本机相连的所有客户端详细信息 |
| crst | 将所有客户端的统计信息重置(谨慎使用) |
| stat | 列出客户端的简要信息 |
| envi | 打印ZK服务的环境变量 |
| mntr | ZK集群健康信息 |
| wchs | watchs的简要信息 |
命令的使用如下,将具体的命令、ZK地址、端口替换即可:
echo ${command} | nc ${zk_server_ip} ${zk_server_port}
第二种:使用JMX
ZK默认是打开JMX的,用户只需要设置环境变量JMXPORT即可(3.4.12版本,其他版本没测)。具体做法是在打开{zk_install_path}/bin/zkServer.sh文件,在最上方加入JMXPORT={port}即可。然后可通过jconsole测试是否开启成功。

知道了如何获取监控数据,接下来我们就可以设计一套监控系统了。话不多说,直接上方案。
方案一:push模式
设计要点:
每个ZK节点安装一个采集器;
采集器每隔一段时间以UDP方式将监控数据发到监控系统;
监控系统启动一个UDP服务,以接受数据。

实现要点:
监控数据的采集采用ZK提供的四字命令来获取ZK状态;
为实现方便,采集器采用python来开发;
UDP服务用netty即可。
我们可以用python与本机建立连接,获取监控信息,再发送给监控服务器。采集器核心代码如下:
s = socket.socket()s.connect((host, int(port)))s.send(cmd)
方案二:pull模式:
监控系统启动定时任务,从ZK节点直接获取数据,可通过socket发送命令或JMX。

方案的对比:
第一种方案扩展性较好,适合大型集群,开发工作量偏大。第二种方案简单,适合小型集群使用。
要重点注意Zookeeper哪些指标
zk_approximate_data_size:快照体积,ZK保存数据的大小。这个值不要太大,太大的原因多半是业务使用不规范,将大量数据存储到ZK中。ZK不是为通用文件存储设计的,切记!
zk_znode_count:znode的数量,所有数据其实都是由一个名为DataTree的数据结构管理。如果节点过多势必影响ZK事务的执行速度。
zk_followers zk_synced_followers:zk_followers是集群follower数量,zk_synced_followers是跟leader同步的follwer数量,这两个值正常情况下应该相等。不相等需及时处理;
zk_num_alive_connections:活跃连接数,要注意是否过多;
zk_watch_count: watch的数量;
zk_packets_sent/zk_packets_received: 发送与接收数据包的量,要注意波动是否很明显,有没有流量激增情况;
zk_avg_latency/zk_max_latency:请求的延迟平均值与最大值;
zk_open_file_descriptor_count:打开的文件句柄数;




