尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ZooKeeper 从裸奔到全副武装:搭建、可视化、监控、告警、看板一条龙

ZooKeeper 从裸奔到全副武装:搭建、可视化、监控、告警、看板一条龙 摘要ZooKeeper 从裸奔到全副武装的一条龙用 Docker 搭建 3 节点 HA 集群或单机ZooNavigator 做 Web 可视化dabealu/zookeeper-exporter 采指标交 Prometheus配 12 条覆盖节点不可达、无 Leader、延迟、连接数、Watch、FD 等的告警规则最后导入 Grafana 看板 11442一眼看穿集群健康。你的 ZooKeeper 还在裸奔吗搭完集群就扔在那里既没有 UI 查看数据也没有监控告警出了问题全靠echo ruok | nc这篇文章带你用 Docker 一条龙搞定 ZooKeeper 的搭建、可视化管理、Prometheus 监控、告警规则和 Grafana 看板——从此告别ZK 挂了半天才发现的社死现场。网上相关文章大多比较零散搭建归搭建、监控归监控想要完整走通一遍得开好几个标签页来回跳。本文把这些环节全部整合到一起照着做就能一次跑通。一、集群搭建1. 方案选择部署 ZooKeeper 集群一般两种方案方案节点数适用场景高可用HA 集群3 台机器各部署 1 个 ZK生产环境、测试环境✅单机模式1 台机器 1 个 ZK本地开发、资源紧张❌ 网上有些教程教你在 1 台机器上跑 3 个 Docker 容器来模拟集群——听起来很热闹但机器一挂三个容器手拉手一起走跟单节点没什么本质区别。花里胡哨不如老老实实单机模式。2. HA 集群搭建推荐三台机器每台跑一个 ZooKeeper 实例互相通信组成集群。前置准备三台机器都执行mkdir-p/data/zookeeper/data /data/zookeeper/datalog节点 1zk-node1echo1/data/zookeeper/data/myiddockerrun-d\--namezk1\--hostnamezk1\--restartalways\-p2181:2181\-p2888:2888\-p3888:3888\-eTZAsia/Shanghai\-eZOO_MY_ID1\-eZOO_SERVERSserver.10.0.0.0:2888:3888;2181 server.2zk-node2:2888:3888;2181 server.3zk-node3:2888:3888;2181\-eZOO_4LW_COMMANDS_WHITELISTmntr,ruok,conf,srvr\-v/data/zookeeper/data:/data\-v/data/zookeeper/datalog:/datalog\zookeeper:3.9节点 2zk-node2echo2/data/zookeeper/data/myiddockerrun-d\--namezk2\--hostnamezk2\--restartalways\-p2181:2181\-p2888:2888\-p3888:3888\-eTZAsia/Shanghai\-eZOO_MY_ID2\-eZOO_SERVERSserver.1zk-node1:2888:3888;2181 server.20.0.0.0:2888:3888;2181 server.3zk-node3:2888:3888;2181\-eZOO_4LW_COMMANDS_WHITELISTmntr,ruok,conf,srvr\-v/data/zookeeper/data:/data\-v/data/zookeeper/datalog:/datalog\zookeeper:3.9节点 3zk-node3echo3/data/zookeeper/data/myiddockerrun-d\--namezk3\--hostnamezk3\--restartalways\-p2181:2181\-p2888:2888\-p3888:3888\-eTZAsia/Shanghai\-eZOO_MY_ID3\-eZOO_SERVERSserver.1zk-node1:2888:3888;2181 server.2zk-node2:2888:3888;2181 server.30.0.0.0:2888:3888;2181\-eZOO_4LW_COMMANDS_WHITELISTmntr,ruok,conf,srvr\-v/data/zookeeper/data:/data\-v/data/zookeeper/datalog:/datalog\zookeeper:3.9注意每个节点的ZOO_SERVERS中自己的地址要写0.0.0.0其他节点写对方的主机名或 IP。原因不是规矩是绑定语义ZK 启动时要在自己那一条server.N上监听 2888/3888。桥接网络下容器拿到的是私有 IP写成自己的主机名解析出来的是宿主机 IP容器内根本绑不上那个地址进程会起不来或选不出 Leader写0.0.0.0表示本机所有网卡都监听才绑得住。其他节点必须写可达地址——那是拿来发起连接的写0.0.0.0就成了连自己。网络模式二选一别混用上面这套桥接 -p端口映射三台机器互相能解析zk-node1/2/3才行配/etc/hosts或内网 DNS自己那条写0.0.0.0。--network host容器直接共享宿主机网络栈省掉端口映射的麻烦。但要同时删掉全部-p参数——host 模式下端口映射不再生效留着只会误导后来看配置的人。生产环境更推荐 host 模式ZK 节点间通信频繁少一层 NAT 少一层排查成本。3. 单机模式搭建资源有限或者只是本地开发一行命令搞定dockerrun-d\--namezookeeper\--hostnamezookeeper\--restartalways\-p2181:2181\-eTZAsia/Shanghai\-eZOO_MY_ID1\-eZOO_4LW_COMMANDS_WHITELISTmntr,ruok,conf,srvr\-eZOO_SERVERSserver.10.0.0.0:2888:3888;2181\-v/data/zookeeper/data:/data\-v/data/zookeeper/datalog:/datalog\zookeeper:3.9二、可视化管理集群跑起来了总不能每次都zkCli.sh敲命令看数据吧那体验跟用记事本写代码差不多。我们需要一个 Web UI。1. 方案对比市面上常见的两个 ZooKeeper Web UI维度juris/zkui基于 DeemOpen/zkuielkozmon/zoonavigatorGitHub Stars~2k~444最后活跃多年未更新需要 Java 72023 年支持 ZK 3.5.x ~ 3.9.xDocker 镜像5 年 未更新持续维护UI 风格传统 Jetty Freemarker有年代感现代 Web UI体验流畅功能CRUD、导入导出、变更历史、搜索、REST APICRUD、节点编辑/浏览、HTTPS、Auto Connect认证内置用户名密码admin/readonly连接时输入 ZK 地址可配置 Auth配置方式需要挂载 config.cfg纯环境变量对 Docker 更友好Stars 多不代表好用。zkui 的 Stars 是历史积累但 Docker 镜像 5 年没更新了基础镜像的安全漏洞怕是能凑一副扑克牌。推荐 ZooNavigator。2. 部署 ZooNavigatordockerrun-d\--namezoonavigator\--restartalways\-p9002:9000\-eTZAsia/Shanghai\-eHTTP_PORT9000\elkozmon/zoonavigator浏览器访问http://你的服务器IP:9002/输入 ZK 连接串如zk-node1:2181,zk-node2:2181,zk-node3:2181点击 Connect 即可。连接界面数据浏览简洁清爽节点树一目了然CRUD 操作点点鼠标就行。三、Prometheus 监控光搭不监控等于买了车不装仪表盘——跑多快、油还剩多少、发动机有没有冒烟全靠感觉。1. Exporter 选型Docker Hub 上拉取量超过 100 万的 ZooKeeper Exporter 有 3 个特性dabealujavsalgarjosdotsocarlpettDocker 拉取量~194 万~210 万最高~108 万采集方式4LW: mntr ruok4LW: mntr推测4LW: mntr srst多节点支持✅ 逗号分隔❓ 未知❌ 仅单节点默认端口914180809141Docker 镜像更新2022-11-132018-10-152018-03-30源码可用性✅ GitHub 可访问❌ 404 已删除上游 carlpett 可访问采集后重置 ZK 统计❌ 不会❓ 未知⚠️ 会默认开启配套 Grafana 看板✅ ID 11442❌❌镜像大小~7 MB~4.2 MB~4.7 MBjavsalgar 拉取量最高但源码 404 了属于人走茶凉型选手。josdotso 默认采集完会重置 ZK 统计数据有点阅后即焚的意思。综合推荐dabealu/zookeeper-exporter——支持多节点、有配套看板、不搞破坏。2. 部署 Exporterdockerrun-d\--namezk-exporter\-p9141:9141\--restartalways\dabealu/zookeeper-exporter\-zk-hostszk-node1:2181,zk-node2:2181,zk-node3:2181\-timeout5\-listen0.0.0.0:9141一个 Exporter 实例就能采集全部 3 个 ZK 节点的指标不用每台机器都部署。3. Prometheus 配置在prometheus.yml中添加scrape_configs:-job_name:zookeeperstatic_configs:-targets:[exporter-host:9141]metric_relabel_configs:-source_labels:[zk_host]target_label:instance⚠️关键配置metric_relabel_configs这段不能省因为 3 个 ZK 节点的指标都从同一个 Exporter 端口出来Prometheus 默认会把instance标签都标记为 Exporter 的地址。加上这段 relabelPrometheus 会用 Exporter 返回的zk_host标签覆盖instance这样 Grafana 里才能区分出 3 个节点。配置完后重载 Prometheuscurl-XPOST http://prometheus-host:9090/-/reload四、告警规则监控不配告警 装了摄像头但不看录像。下面是一套经过实践验证的 ZooKeeper 告警规则覆盖了从服务挂了到快要挂了的各种场景。1. 规则总览规则级别触发条件说明Exporter 不可用 criticalup 0Exporter 本身挂了此时下面所有 zk_ 指标都没数据单个 ZK 节点不可达 criticalzk_up 0最容易漏配的一条见下方说明健康检查失败 criticalzk_ruok 0节点连得上但 ruok 不回 imok无 Leader 节点 critical集群中检测不到 leader集群脑裂或全部挂掉平均延迟过高 warningzk_avg_latency 100ms响应变慢该查原因了最大延迟过高 warningzk_max_latency 5000ms偶发慢请求未完成请求堆积 warningoutstanding_requests 50处理不过来了连接数过高 warningalive_connections 500连接泄漏客户端太多临时节点过多 warningephemerals_count 10000服务注册过多Watch 数过多 warningwatch_count 50000Watch 泄漏风险文件描述符不足 warningFD 使用率 85%再不处理就要 Too many open files 了Follower 同步延迟 warningpending_syncs 5主从同步跟不上⚠️zk_up这条一定要配否则挂一个节点你收不到任何告警。前面为「一个 Exporter 管 3 个节点」叫好但它有个代价Prometheus 的up监控的是 Exporter 的抓取状态不是 ZK 节点的状态。Exporter 活着up就恒等于 1。更隐蔽的是翻 Exporter 源码可以看到某个 ZK 节点连不上时它只发一条zk_up{zk_hostx} 0然后continue跳过——该节点其余所有指标含zk_ruok压根不会产生。而 PromQL 对不存在的时间序列不产生任何结果所以zk_ruok 0也匹配不到。结果就是 3 节点集群挂掉一个 follower 时up是 1、zk_ruok序列消失、leader 还在——上面三条 critical 一条都不报。只有zk_up 0能精确抓到它。一句话up管 Exporterzk_up管 ZK 节点两条都要。2. 告警规则文件将以下内容保存为 Prometheus 的 rules 文件如zookeeper-alerts.ymlgroups:-name:zookeeper-alertsrules:# --- Critical 级别 ----alert:ZooKeeperExporter不可用expr:up{jobzookeeper} 0for:1mlabels:severity:criticalgroup:zookeeperannotations:summary:ZooKeeper Exporter 不可用description:Exporter {{ $labels.instance }} 抓取失败所有 ZK 指标已失去数据来源# 注意up 只反映 Exporter 的抓取状态单个 ZK 节点挂掉它仍是 1# 必须靠 zk_up 才能定位到具体是哪个节点不可达-alert:ZooKeeper节点不可达expr:zk_up 0for:1mlabels:severity:criticalgroup:zookeeperannotations:summary:ZooKeeper 节点不可达description:ZooKeeper 节点 {{ $labels.zk_host }} 连接失败该节点其余指标已停止上报-alert:ZooKeeper健康检查失败expr:zk_ruok 0for:1mlabels:severity:criticalgroup:zookeeperannotations:summary:ZooKeeper 健康检查失败description:ZooKeeper {{ $labels.instance }} ruok 返回异常-alert:ZooKeeper无Leader节点expr:sum(zk_server_leader) 0for:1mlabels:severity:criticalgroup:zookeeperannotations:summary:ZooKeeper 集群无 Leaderdescription:ZooKeeper 集群中没有 Leader 节点服务可能不可用# --- Warning 级别 ----alert:ZooKeeper平均延迟过高expr:zk_avg_latency100for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 平均延迟过高description:ZooKeeper {{ $labels.instance }} 平均延迟: {{ $value }}ms超过 100ms-alert:ZooKeeper最大延迟过高expr:zk_max_latency5000for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 最大延迟过高description:ZooKeeper {{ $labels.instance }} 最大延迟: {{ $value }}ms超过 5000ms-alert:ZooKeeper未完成请求堆积expr:zk_outstanding_requests50for:3mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 未完成请求堆积description:ZooKeeper {{ $labels.instance }} 排队请求数: {{ $value }}超过 50-alert:ZooKeeper连接数过高expr:zk_num_alive_connections500for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 连接数过高description:ZooKeeper {{ $labels.instance }} 活跃连接数: {{ $value }}-alert:ZooKeeper临时节点过多expr:zk_ephemerals_count10000for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 临时节点过多description:ZooKeeper {{ $labels.instance }} 临时节点数: {{ $value }}-alert:ZooKeeperWatch数过多expr:zk_watch_count50000for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper Watch 数过多description:ZooKeeper {{ $labels.instance }} Watch 数: {{ $value }}超过 50000-alert:ZooKeeper文件描述符不足expr:zk_open_file_descriptor_count / zk_max_file_descriptor_count * 10085for:5mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper 文件描述符使用率过高description:ZooKeeper {{ $labels.instance }} FD 使用率: {{ printf \%.1f\ $value }}%-alert:ZooKeeper同步延迟expr:zk_pending_syncs5for:3mlabels:severity:warninggroup:zookeeperannotations:summary:ZooKeeper Follower 同步延迟description:ZooKeeper {{ $labels.instance }} 待同步数: {{ $value }}配置完成后访问 Prometheus 的 Alerts 页面可以看到所有规则已加载绿色表示正常红色/黄色表示触发告警——一眼就能看出集群有没有闹情绪。五、Grafana 看板最后一步让数据变成好看的图表。导入 Grafana 看板ID: 11442这个看板是专门为dabealu/zookeeper-exporter设计的。⚠️ 注意Grafana 上其他 ZooKeeper 看板大多是为不同 Exporter 设计的直接导入会出现一片空白数据全无的尴尬场面。认准11442。导入方式Grafana → 左侧→ Import → 输入11442→ Load → 选择 Prometheus 数据源 → Import。效果如下六、总结一张图回顾整条链路ZooKeeper 集群3 节点 ↓ 四字命令mntr / ruok zk-exporterdabealu ↓ /metrics Prometheus采集 12 条告警规则 ↓ Grafana看板 11442 AlertManager告警通知 ↓ ZooNavigator日常查看数据环节工具一句话总结搭建zookeeper:3.93 台机器每台一个容器稳如老狗可视化elkozmon/zoonavigator现代 UI告别 zkCli.sh 盲敲采集dabealu/zookeeper-exporter一个 Exporter 管 3 个节点监控Prometheus Grafana 11442指标可视化一眼看穿集群状态告警Prometheus Rules12 条规则从挂了到快挂了全覆盖up管 Exporter、zk_up管节点缺一不可从此你的 ZooKeeper 不再裸奔。如果这篇文章帮你省下了半天折腾时间点个赞就是对我最大的鼓励。有问题欢迎评论区交流看到必回。延伸阅读Redis 集群从裸奔到全副武装搭建、可视化、监控、告警、看板一条龙 —— 同款一条龙套路把 Redis 集群也配齐可视化与监控RocketMQ 5.x 从裸奔到全副武装监控、告警、看板一条龙 —— 同一套监控方法论换成 RocketMQ 的监控看板落地Prometheus Grafana AlertManager 监控体系搭建Docker 一把梭 —— 本文告警与看板依赖的监控底座从零搭一遍️ 标签ZooKeeperPrometheus 监控Grafana 看板zookeeper-exporterZooNavigator告警规则
返回列表