一. 前言
作为运维人员,对监控系统不会陌生,每个运维都会熟悉几款监控工具;像版本快速迭代的Zabbix、社区用户活跃度较高的Prometheus、小米开源监控系统Open-faclon等监控系统工具。
笔者最近在学习Kubernetes,Kubernetes 是 Google Borg 系统的开源实现,于此对应 Prometheus 则是 Google BorgMon 的开源实现。因此Kubernetes和Prometheus具有很高得容错性和集成性。
带着一丝兴趣对Prometheus进行调研,并且在公司最新的项目初步使用;经过半个月的学习,发现Prometheus与Zabbix在使用上、个性化、配置上还是有相当大的差别,下面将对这2款监控系统工具说说自己的体会。
着重说明下,本文并不是吐槽或者说是贬低某个工具,只是把自己的使用经验和了解程度进行杂谈,并不是说越前沿的技术越厉害就一定要去使用,只有认真剖析过自己的项目架构且与自己的项目具有很高容错性监控工具才是最好的
二. Zabbix与Prometheus的简介
2.1 Zabbix
Zabbix,由C语言和PHP语言开发,核心组件Zabbix-server、Zabbix-agent,当架构庞大时还需要借用数据代理Zabbix-proxy,自身支持2钟数据采集方式和采集多种客户端,同时支持SNMP、JXM、ICMP、Telnet等多种协议,它将采集到的数据存放到数据库中,然后对其进行分析整理,如果符合告警规则,则触发相应的告警。
下图为笔者项目中Zabbix使用架构
2.1 Prometheus
Prometheus 是由 SoundCloud 开发的开源监控报警系统和时序列数据库。Prometheus 的基本原理是通过 HTTP 周期性抓取被监控组件的状态,任意组件只要提供对应的 HTTP 接口并且符合 Prometheus 定义的数据格式,就可以接入 Prometheus 监控。
下图为笔者项目中Prometheus使用架构 http://tcandyj.top:9090
三. Zabbix与Prometheus的使用区别到底在哪?
3.1 就自身架构而言
3.1.1 Zabbix
对用过Zabbix的人来说,部署有时候是一件很痛苦的时候,特别是make方式,不知道会出现什么样的环境问题,甚至需要手动处理第三方库,网上处理方式基本千篇一律,没有对问题进行实质性解决说明,一个完整的Zabbix架构必须要有server端和agent端,若架构规模允许proxy代理也需要。
3.1.2 Prometheus
相比Zabbix,Prometheus安装方式很简单,直接tar包解压就直接可以启动;若想实现监控,只需要部署一个server端即可,但是自身依赖的组件较多,不像Zabbix功能集成一体,告警需要Alertmanager、自定义Key需要Pushgateway;但是安装这些依赖组件部署方式也是很简单,不像Zabbix考验部署人的心态。
它自身依赖的组件较多,维护起来比Zabbix更麻烦,需要的节点更多,因为生产时不允许单点故障。
3.2 就配置启动而言
3.2.1 Zabbix
Zabbix自身配置比较简单,agent直接指明server或proxy地址,外加一点参数优化就可以直接启动服务。
3.2.2 Prometheus
Prometheus的配置基本不需要改就可以直接启动,想去优化也很难找到相关配置,基本就是tar解压就能用的那种。
3.3 就数据采集方式而言
3.3.1 Zabbix
Zabbix支持2种数据采集方式,主动模式和被动模式,一种是server端主动拉取数据,在server端配置对应ip地址段即可,但是不够安全,若生产环境中ip地址段较多且没有规律,需要配置大量ip地址段,而且还有可能会把同网段非自身项目的机器监控到;另一种是agent主动传输数据,配置唯一标识符进行认证,这种方式比较简单,具有统一规划性。
Zabbix采集服务器数据一般都会直接调用自身"Template on Linux OS"、"ICMP"模板,模板下有很多监控项,如"filesystem"、"network"、"process"、"ping loss”等,每一个监控项都可以根据自身业务规则进行个性化模板修改,如采集间隔频率、数据存留周期、在什么时间段进行采集或告警,相比而言比较灵活。
3.3.2 Prometheus
Prometheus仅支持监控数据主动拉取方式,基于HTTP协议实现。
在项目使用Prometheus期间,发现无法对不同的监控项进行采集频率修改,所有采集数据频率均使用全局配置;网络丢包率,是在一定时间内,采集成功且探测正常的次数占总采集次数的百分比;生产上每一个监控项采集频率都是1s一次的话显然不合理,这样会造成不必要的api访问;但是个人感觉Prometheus应该不会这么low,针对这块问题笔者还在调研中。
3.4 就自身监控项而言
3.4.1 Zabbix
Zabbix自身支持很多模板,如ICMP、Linux OS Template、MySQL Template、JVM等等,每一种模板下面有多个item监控项,只需要将主机关联至一个或多个模板即可。Zabbix自身已经集成了很多数据采集的规则,当然也可以根据自身的业务特点去做二次修改,但是内容格式比较晦涩难懂。
最重要一点的就是,Zabbix自身实现的数据采集规则,很多使用者只是因为要用而用,并不理解其中监控规则以及数据表达含义。比如Zabbix自身实现的Cpu负载,很容易误导使用者认为是服务器整体Cpu负载,但实际是每一颗Cpu使用负载。一般而言关注的服务器整体性能,而不是某颗Cpu的性能。
3.4.2 Prometheus
Prometheus自身不支持数据采集,但是它却支持很多拓展组件进行数据采集,每一个组件实现不同类型的数据采集;node_exporter采集服务器整体性能数据、blackbox_expoter实现web http,icmp,port等数据采集、process_exporter对服务器进程数据进行采集,提供对开源组件已封装好的数据采集工具,如mysql、memcache、haproxy等;
与Zabbix最大的区别,Prometheus的监控项需要自己去定义,灵活性很强,笔者觉得没有你做不到的,只有你想不到的。使用内存通常是TotalMem-FreeMem-BufferMem-CacheMem,但是针对高IO型程序或脚本,CacheMem就得需要时刻关注了。
Zabbix和Prometheus的监控项,笔者更偏向Prometheus些,因为它的个性化规则实在是太强了,可以结合内置的聚合操作实现统一监控项的不同数据展示。在自定义监控项的同时,能让使用者更深入的去了解数据含义以及性能指标。
3.5 就自定义监控而言
2者都支持丰富的自定义监控项,但是Prometheus需要借助Pushgateway组件来实现数据的中转。
3.5.1 Zabbix
Zabbix自定义监控项都是在agent上编写脚本,当监控规模较大时,有着牵一发而动全身的感觉,传输脚本、定时任务、修改配置、重启服务,若采集数据超过30s还会报错,整体操作流程显得很繁琐。但是它自身有一个很强大的自定义监控项,那就是LLD规则,模板中的network、filesystem就是使用LLD规则实现,按照json数据格式去实现,通过lld能够很好的解决百台服务器tcp端口监控问题。
3.5.2 Prometheus
Prometheus自定义监控需要Pushgateway组件来实现数据中转,像这种数据处理核心组件必然会面临单点问题,一般需要做双活。实现自定义监控,只需要在客户端上传输脚本、定时执行即可,将采集数据同步给Pushgateway,Prometheus通过http协议主动从Pushgateway拉取数据。
上段中提到过,Prometheus个性化监控规则特别灵活,以至于灵活到也有让人蛋疼的时候,百台服务器tcp端口监控,按照标准化规则,相同应用模块为一组json文件,提供不通功能的应用模块分别放置不同的目录用于区分,虽然很有规范性,但是实施起来还是很比较容易耗时的,但是好处是动态加载json文件,当新增或删除tcp端口监控项时不需要重启服务,Prometheus会基于配置时间去动态加载扫描。
这里附上一个对tcp 连接状态的自定义监控脚本,用于参考#!/usr/bin/python
# -*- coding: utf-8 -*-
# author:wtc
"""
Created on 2021/6/23 15:51
"""
import sys
import socket
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
sys_st = {
"00": "ERROR_STATUS",
"01": "TCP_ESTABLISHED",
"02": "TCP_SYN_SENT",
"03": "TCP_SYN_RECV",
"04": "TCP_FIN_WAIT1",
"05": "TCP_FIN_WAIT2",
"06": "TCP_TIME_WAIT",
"07": "TCP_CLOSE",
"08": "TCP_CLOSE_WAIT",
"09": "TCP_LAST_ACK",
"0A": "TCP_LISTEN",
"0B": "TCP_CLOSING",
}
if __name__ == "__main__":
tcp_status_dict = {}
hostIP=socket.gethostbyname(socket.gethostname())
try:
tcp_path,metric_name = sys.argv[1:]
except Exception as e:
exit()
with open(tcp_path,"r",encoding="utf8") as tcp_file:
for line in tcp_file:
tcp_status_code = line.strip().split()[3]
if tcp_status_code in sys_st:
if tcp_status_dict.get(sys_st[tcp_status_code]) is None:
tcp_status_dict[sys_st[tcp_status_code]] = 1
else:
tcp_status_dict[sys_st[tcp_status_code]] += 1
for inc_tcp_status,count_status in tcp_status_dict.items():
registry = CollectorRegistry()
"""
Guage(metric_name,labels_name,registry=registry)
"""
data_model=Gauge(metric_name, "Monitor_tcp_netstat", ['instance', 'service', 'use'], registry=registry)
data_model.labels(hostIP, inc_tcp_status, "tcp_netstat").set(count_status)
push_to_gateway(hostIP+":9091", job='tcp_netstat_'+inc_tcp_status, registry=registry) 3.6 就告警而言
就告警而言,2者都有各自的优势。既都支持短信,也支持微信、钉钉。
使用Zabbix告警,需要自己写脚本去调用Api接口去实现短信、微信、钉钉告警,但是Prometheus只需要在配置中指明相关参数既可以实现,封装好的接口。
当服务器宕机时,Zabbix的告警风暴就来了,服务器宕机、端口探测异常、服务器重启、网络不通等各种告警蜂拥而至,给人一种迷惑感,不知道是因为什么问题导致一系列的告警。但Prometheus自身有分组、抑制、静默三种策略,能够对同一组同一时间多条告警进行汇总统一发出,将连锁反应的告警源头进行通知,而不是有一种狼来了的感觉,但是Prometheus自身不支持告警次数限制,这点比较蛋疼,希望后期支持这个功能。
3.7 就移植性而言
Zabbix agent依赖配置文件,其中部分参数有对IP、主机名的修改,这就等于与主机进行了绑定关联。
Prometheus的告警规则、监控规则都是在server端实现,客户端只需要部署对应的exporter或脚本即可,不管是在物理机、厂商云服务器上还是个人私有云上,都可快速迁移使用,需要修改server采集数据的ip即可。
3.8 就数据查询而言
Prometheus 用的就是自研 TSDB数据库,Zabbix 则用的是 MySQL 或 PostgreSQL。
对于时序型数据库笔者了解并不多,粗浅的来看,Prometheus 的时序型数据库在高并发的情况下,读写性能是远高过传统的关系型数据库的,另外还提供了很多内置的基于时间的处理函数,简化数据聚合的难度。也许这不能简单的理解为两种数据库的特性造成的结果,但至少说明,对专门监控场景进行存储优化,是十分必要的。
笔者模拟十万级监控数据,Prometheus数据查询速率比Zabbix更快。
四. 总结
就笔者来看,监控系统没有绝对的谁好谁不好,最重要的是适合自己的团队,能够合理利用最小的成本解决问题。
Zabbix 的成熟度更高,上手更快,但更好的集成导致灵活性较差,问题更大是,监控数据的复杂度增加后,Zabbix 做进一步定制难度很高,即使做好了定制,也没法利用之前收集到的数据了(关系型数据库造成的问题)。
Prometheus 基本上是正相反,上手难度大一些,但由于定制灵活度高,数据也有更多的聚合可能,起步后的使用难度远小于 Zabbix。尤其是PromSQL强大的表达式,相对于Zabbix这种UI操作,学习的门槛比较高。
|