Zookeeper简介
Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统。
简单来说就是一个Zookeeper注册同步中心,内部结构为一个树形目录,每个节点上可以存放一定量(默认的数据量上限是1M,但是可以通过调整参数修改)的数据,客户端(一段通过Zookeeperapi编写的程序或者一个cmd和shell窗口)连接Zookeeper后,可以在任何节点上注册监听(watcher),当节点被删除或者节点上的数据有变化时,Zookeeper会主动触发注册在当前节点上的监听程序。
同时Zookeeper类似于文件系统,各个节点都可以配置不同的读写访问权限。
zookeeper本身是支持多个zookeeper组成集群,利用选举机制选出负责不同职责的角色,本文暂不涉及。
案例
备注:由于全文粘贴代码实在不好排版,本文代码相关部分,只介绍了相关片段,完整的请下载后查看。
界面示例(动效):
本文利用Zookeeper节点可存放数据以及节点可监听的机制,借助WebSocket实现对多个服务器的实时监控。具体web端效果如下(由于是模拟,界面略显粗糙):
可以同时打开多个浏览器,接收WebSocket推送的实时监控数据。
实现逻辑
实现过程
本文用到maven以及websocket,这两部分内容本文只做配置介绍,相关知识需自己提前掌握。同时zookeeper的详细命令和api也不做详细解释,可自己试验。
环境:
eclispe Oxygen Release (4.7.0);
maven 3.2.2
Zookeeper3.4.13
win10环境(一般线上都是linux环境,这里为了省事所有都在自己的笔记本上折腾的,所以用了win环境)
1、Zookeeper的安装
安装比较简单,这里略过,下载后解压,配置zoo.cfg里面的目录参数,完后就可以启动了。
2、启动Zookeeper
打开cmd窗口运行Zookeeper安装目录bin下的zkServer.cmd,即可。
也可写个bat文件,方便每次使用,内容(保存即可,其中d:zookeeper-3.4.13bin是我的zookeeper的bin目录)如下:
cd d:zookeeper-3.4.13bin
d:
zkServer.cmd
@pause
3、创建根目录
通过cmd连接到Zookeeper创建更目录/servers,也可通过java代码来创建。
client的bat启动内容参考如下:
cd d:zookeeper-3.4.13bin
d:
zkCli.cmd -server 127.0.0.1:2181
@pause
回车之后,通过命令create /server serverlist 完成根节点的创建, 后面所有待监控的服务器都在此节点下创建子节点(临时节点)。
关于zookeeper节点的类型,也请自行脑补。
这里根节点为持久化节点,服务器数据节点为临时节点,是因为服务器程序在于zookeeper断开后,需要删除节点,这样才监控程序才能知道服务器下线了。当然实际线上应该都会采用持久化节点,然后通过状态数据来判断,这里就偷懒了。
3、代码编写
maven配置
整个示例有2个项目组成:一个是模拟服务器的程序(定时采集监控指标,把指标数据更新到node上),一个是监控程序(用于监控zookeeper节点变化,并获取节点数据计算阈值,并通过Websocket推送数据到浏览器)。
business-server(服务器指标采集程序)的maven配置
只依赖zookeeper的jar:
business-server-monitor(监控程序)的maven配置:
由于有web界面,所以需依赖Servlet、JavaEE相关包,同时容器采用了maven的jetty插件,关于maven配置jetty以及如何启动可以参考上一篇文章中的相关介绍:模块化编程及Maven配置最佳实践之一。
当然实现Websocket的方式有很多,比如SpringMvc,SpringBoot等等,这里为了防止太多干扰就用了原生写法。具体maven配置如下:
1、business-server(服务器指标采集程序) 代码片段:
代码逻辑为:启动后(main方法)连接zookeeper并建立临时节点,同时初始化数据,之后启动模拟指标采集的线程,间隔一段时间生成随机指标数据。
创建临时节点代码片段:
其中ACL是zookeeper的节点访问权限配置,也需要自行脑补。
模拟指标变化并将数据更新到节点上
其中ServerData是我自己创建的bean对象,用于存放服务器指标,如下:
主要包含3个模拟指标,cpu,内存,磁盘,可自己添加。指标和zookeeper无关。
至此采集程序代码就结束了。
2、business-server-monitor(监控程序)实时监控zookeeper节点变化并推送数据的代码片段
项目启动采用了JavaEE的ServletContextListener监听启动的方式来启动和Zookeeper的连接,需要在web.xml配置这个Listener。
继承ServletContextListener
当jetty容器初始化后,触发建立和zookeeper的连接并注册监听:
然后通过Zookeeper api中的的getChildren获取节点数据并启动监听,
List servers = zk.getChildren(ServerData.serverRootNode, true);
当节点发生数据变化时触发监听的process方法,process方法获取根节点下的所有子节点的数据并封装成ServerData对象列表,用于websocket推送。
之后通过Websocket推送到浏览器:
Websocket配置很简单,只需要注释上先关annotation(@ServerEndpoint)即可,无需其他配置,容器启动时会自行扫描到此类。
推送数据这里就简单了拼接成了html,界面上就直接放在div就行了。
3、monitor.jsp获取实时监控数据
以上便是这个例子的完成介绍过程。