写点什么

PPTV 的 Zabbix 监控体系

2016 年 9 月 28 日

编者按:InfoQ 开设新栏目“品味书香”,精选技术书籍的精彩章节,以及分享看完书留下的思考和收获,欢迎大家关注。本文节选自姚仁捷著《Zabbix 监控系统深度实践》中的第 23 章“PPTV 的 Zabbix 监控体系”,以 PPTV 的监控体系为例,给大家一个完整的实战说明。前半部分主要介绍 PPTV 基于 Zabbix 进行的二次开发,后半部分介绍 Zabbix 在整个监控体系中的角色和作用。

1 Python Zabbix API

在 PPTV 的运维开发团队,主要的开发语言是 Python,因为 Python 入门简单,开发快速,而且是一个“电池都包括”的语言(表示 Python 的各种库应有尽有)。Zabbix 虽然用起来不算困难,但都需要鼠标操作,没办法集成到命令行中。Zabbix 本身提供了 API 接口,但是封装的不是很好,不是面向对象的建模,要记忆这么多方法也不容易。因此,笔者参照其他人开发的 Zabbix API,用 Python 写了一个模块——ZabbixPythonApi。它的作用是在 Zabbix API 上根据 Zabbix 对象封装了一层,让我们在使用 API 的时候是基于对象的。Zabbix Python Api 已经开源在 Github 上了,地址为: https://github.com/baniuyao/ZabbixPythonApi 。这个 API 是基于 Zabbix 1.8.8 开发的,在 Zabbix 2.2 也可以运行。

使用起来很简单,首先需要引入我们的 API 模块:

复制代码
from zapi import ZabbixAPI

接着是登录 Zabbix:

复制代码
zapi = ZabbixAPI(url='http://your.zabbix.address', user='admin', password='zabbix'
zapi.login()

然后就是针对资源的操作,比如查找名字为“HostABC”的 host:

复制代码
zapi.Host.find({‘hostname’:’HostABCr’})

返回值如下:

复制代码
[{
'available': '1',
'disable_until': '0',
'error': u'',
'errors_from': '0',
'flags': '0',
'host': 'HostABC',
'hostid': '10108',
'ipmi_authtype': '-1',
'ipmi_available': '0',
'ipmi_disable_until': '0',
'ipmi_error': u'',
'ipmi_errors_from': '0',
'ipmi_password': u'',
'ipmi_privilege': '2',
'ipmi_username': u'',
'jmx_available': '0',
'jmx_disable_until': '0',
'jmx_error': u'',
'jmx_errors_from': '0',
'lastaccess': '0',
'maintenance_from': '0',
'maintenance_status': '0',
'maintenance_type': '0',
'maintenanceid': '0',
'maintenances': [],
'name': 'HostABC',
'proxy_hostid': '0',
'snmp_available': '0',
'snmp_disable_until': '0',
'snmp_error': u'',
'snmp_errors_from': '0',
'status': '1',
'templates': [{'hostid': '0', 'templateid': '0'}]
}]

是不是返回的属性特别多?Zabbix API 会返回这个搜索到的 Host 的所有属性。可以在 find 方法中加入一个参数,使得 find 方法只会得到一个指定的属性,如:

复制代码
zapi.Host.find({'name':'HostABC'}, attr_name='hostid'

这样返回的就仅仅是搜索到的 Host 的“hostid”这个属性的值了:

复制代码
['10108']

通过这个例子,大家应该能举一反三了吧。使用 API 时传递的参数(比如上面例子中的 name),可以参考 Zabbix 的官方文档。

2 Spider——服务器添加 Zabbix 监控

使用监控系统最大的问题,就是添加监控。在 PPTV 使用 Zabbix 的初期,添加监控非常麻烦。需要根据服务器上面运行的应用程序,去添加对应的监控。比如运行了 Reids 则要增加对 Redis 的监控,运行了 Nginx 需要添加对 Nginx 的监控。一台服务器还可以手动操作,如果 100 台、1000 台呢?而且,只要是人进行的操作,就是可能会出错的地方。

除了需要人力工作,容易出错外,手动添加服务器监控最大的问题就是无法和自动化运维的其他系统集成。理想的状态是一台服务器上线后,应该能自动添加监控;一台服务器下线,应该自动取消监控。很多公司应该使用的是类似“工单”的东西来进行流程上的控制,当服务器上线时,一张“添加监控工单”会发送给对应的运维工程师,然后运维工程师去进行操作。这一环,会变成整个自动化运维的瓶颈。

面对这种问题,Zabbix 推出了 auto discovery 功能,它设计的初衷就是解决上面提到的自动添加监控的问题。它的设计非常好,但有一些局限,比如它不支持从进程去判断服务器上存活了什么应用,只能从 Zabbix Server 去侦测 Zabbix Agent 上运行了哪些端口,从而去判断运行了哪些程序。而且,自动侦测使用 IP 范围去探测服务器,这个粒度太粗了,很有可能会造成误操作。比如服务器下线这个动作,如果使用了自动侦测,它会一直侦测这个网段,那么这里就隐含了一个限制:删除监控会发生在服务器关机之后(我们使用 Action 来控制超过多久的服务器自动移除监控),这样就会产生误报警。假设监控了一台 Nginx 服务器,现在要下线了,那么确定流量切走以后,会关闭 Nginx 进程,然后关机。而 Zabbix 要在关机后才能删除监控,那么在关闭 Nginx 进程到关机的这段时间,Zabbix 会认为 Nginx 进程已经消失了,这是个问题,会报警。而实际上,这个根本不需要报警。

基于这些需求,笔者开发了 Spider,它的作用简单来说就是根据服务器的 hostname,对运行的应用加入对应的监控,而需要的只是一个 IP。Spider 界面如图所示。

3 Event Console

在查看报警时,Zabbix 做得不是很好。一是每一个报警的维度很少,只能看某个服务器的某个报警,顶多加上一个报警的等级。另外展示报警的方式也不好,不能让人很好地发现问题。而且,虽然 Zabbix 有 ACK 功能,但太过简陋,它只能知道某个人在什么时候 ACK 了这个请求。

在 PPTV 时,除了上海的兄弟们,武汉还有 24 小时值班的工程师,他们一般是第一个接收到 Zabbix 报警的人,他们希望在接收到报警后,对于简单的问题可以直接远程执行命令,或者自动恢复,比如重启 PHP 进程之类。

基于这些需求,我们开发了 EventConsole 平台。它可以展示报警,处理报警。在上面运维工程师可以很方便地看到目前发生了什么问题,以及紧急程度有多高。界面如图所示。

4 Rule Engine

Rule Engine 是 PPTV 报警系统的核心部分。它的作用是根据 Zabbix 中 Action 的信息,组织报警数据,进行发送邮件给对应负责人,将报警推送到 EventConsole,自动执行一些命令,收集出问题时刻的服务器数据等操作。

为什么要开发 Rule Engine?使用 Action 来发送邮件不是挺好的吗?Zabbix 支持很多宏,可以在报警邮件中发送很多东西。我们先撇开 Zabbix,想象一下,如果你收到一封报警,你最希望里面有些什么内容。以我个人来说,我想看到出问题时这台服务器的一些基本系统数据,比如 CPU 负载、内存、哪些进程在跑等。我还想知道出问题的这个监控点的历史数据是怎样的。如果能根据报警内容的不同,事先做一些分析,那是更好的。

Rule Engine 就是为了满足这些需求而设计的。Zabbix 的 Action 不再发送邮件,而是将必要的信息,比如 itemid、triggerid 等传递到后端的 rule_engine_agent,rule_engine_agent 将这条消息发送到 ActiveMQ,然后 rule_engine 从 ActiveMQ 拿到消息,根据报警的类型,去组合不同的报警信息。比如报警内容为 Linux 服务器内存不够了,那么就需要内存使用的排行;如果报警是磁盘 I/O 高,那么就需要消耗 I/O 的排行。当组合好这个报警信息后,一是要发送邮件给对应的运维和研发,二是将消息发送到 Event Console。

在这个处理过程中,在发送报警邮件和发送消息给 Event Console 之前,会访问一个叫做 Snooze Console 的系统,来确定这个报警是否需要发送。“Snooze”操作的作用就是停止某一类报警一段时间。

5 报警系统架构

图示是整个报警系统的架构。报警的消息从触发 Action 开始,将需要的信息(比如 itemid,triggerid 等)发送给 Rule Agent,Rule Agent 将消息转发到 ActiveMQ。Rule Engine 会从 ActiveMQ 中抓取消息,从 Snooze Console 中查询这个报警是否需要处理,再根据报警的类型进
行不同的处理,组合不同的邮件内容,发送邮件或者短信。然后把这个报警消息发给 ActiveMQ。之后,Event Console 会从 ActiveMQ 获取消息,显示在 Event Console 的前端界面中。

书籍介绍

由浅入深,讲解 Zabbix 应用与原理的技术书籍,是作者多年实战经验的总结和浓缩。从工作需求出发,以实际案例为指引,不仅谈及了具体操作,而且讲解了 Zabbix 的设计思路。在概念篇,从一个简单但完整的入门案例讲起,解释概念并介绍如何将服务器加入监控;在进阶篇,介绍 Zabbix 的各方各面的配置;在设计篇,对 Zabbix 的内部原理进行深入剖析,包括 Zabbix 与数据库的交互 Zabbix 数据库表的设计等,并分享作者在 Zabbix 上踩过的坑以及解决问题的思路。最后在开源部分介绍 58 同城开源的 Zatree 和 Chrome 的插件、手机客户端等工具。

2016 年 9 月 28 日 17:363847

评论

发布
暂无评论
发现更多内容

架构师训练营 - Task Week 2

brave heart

极客大学架构师训练营

架构 0 期 -week2- 命题作业

陈俊

极客大学架构师训练营

依赖倒置及 Cache 重构设计

秤须苑

极客大学架构师训练营

架构师训练营第二章 总结

尔东雨田

架构师 0 期第二周作业(心得体会)

何伟敏

软件架构的实现设计总结

mh

第二周 作业

尔东雨田

架构师训练营-第二周学习总结

极客大学架构师训练营

SOLID设计原则(第二周+作业)

林毋梦

极客大学架构师训练营

一笔钱买两次东西?——双花安全问题分析

石君

数字货币 双花攻击 数字货币安全

week02-总结

seki

设计原则之依赖倒置和接口隔离

dapaul

Mybatis-plus 之 DIP

无心水

极客大学架构师训练营

架构师训练营 - Lesson Week 2

brave heart

极客大学架构师训练营

【第二周学习总结】

黑莓

架构师训练营 0 期第二周

Blink

第二周总结

阿布

【第二周作业】

黑莓

架构师训练营学习总结——面向对象的设计模式【第三周】

王海

极客大学架构师训练营

架构训练营第二章作业

mh

设计模式的主要原则

编程这件事

dapaul

【架构】—回归本质(面向对象)

不二架构

面向对象 架构师 极客大学架构师训练营

小师妹学JVM之:JDK14中JVM的性能优化

程序那些事

JVM 「Java 25周年」 小师妹 JIT JDK14

第二章作业

小胖子

架构师如何去进行软件设计(设计原则篇)?

阿飞

极客大学架构师训练营

架构师培训第2周学习总结

Geek_165f3d

第二周学习总结

安阳

【架构课作业 - 第二周】

Nelson

极客大学架构师训练营

架构师训练营-总结2

进击的炮灰

极客大学架构师训练营 框架设计、设计原则、设计模式 第四课 听课总结

John(易筋)

极客时间 极客大学 极客大学架构师训练营 设计原则 框架设计

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

PPTV的Zabbix监控体系-InfoQ