前言

都说监控系统是运维的第三只眼睛,因此一旦线上出问题,业务方第一反应是,监控系统有没有提前告警?是不是告警太多被淹没了?为啥没有把根因报出来?上面的三个质疑,相信做过监控的同学都会深有体会。我做了10年的监控,背锅不少,在2021年的第一天,我想跟你聊一聊我的一些心得。

什么是监控

做监控前,先问自己一个问题。监控的本质是什么?我的理解是测并实施制,监测并告警只是第一步,有效的控制才是根本。

监控restTemplate使用情况 监控平台 ui_监控restTemplate使用情况

监控restTemplate使用情况 监控平台 ui_监控ui_02

  • 数据采集:采集的方式有很多种,包括日志埋点进行采集(通过Logstash、Filebeat等进行上报和解析),JMX标准接口输出监控指标,被监控对象提供RESTAPI进行数据采集(如Hadoop、ES),系统命令行,统一的SDK进行侵入式的埋点和上报等。
  • 数据传输:将采集的数据以TCP、UDP或者HTTP协议的形式上报给监控系统,有主动Push模式,也有被动Pull模式。
  • 数据存储:有使用MySQL、Oracle等RDBMS存储的,也有使用时序数据库RRDTool、OpentTSDB、InfluxDB存储的,还有使用HBase存储的。
  • 数据展示:数据指标的图形化展示。
  • 监控告警:灵活的告警设置,以及支持邮件、短信、IM等多种通知通道。

所以做监控的最终目的是先于用户发现问题,提供有价值的告警,并闭环解决。

监控1.0

08年刚到WS的时候,CDN业务规模还很小,公司就几百台机器,监控项不到20种。当时过去的时候,阿贤已经把监控系统都搭得差不多了,基本能满足业务初期的监控需求,监测服务器的死活,服务状态异常squid/lighttpd/rsync/snmp。

监控restTemplate使用情况 监控平台 ui_监控系统_03

架构说明:

  • pingServer服务端部署在内网,它从CDN平台获取监控组及组对应的监控机,为监控机分配监控测试任务
  • wsPoller对测试任务进行远程测试,并根据测试结果产生报警发送至告警平台
  • 通过SNMPOID扩展增加监控的采集项

存在的问题:

  • 单点策告警,容易误报
  • wsPoller无法根据自身的网络、负载自动踢除
  • 机器性能监控缺失
  • 不支持本地采集

监控2.0

随着客户对服务质量的要求变高,监控1.0的弊端开始显露。09年初,我们决定开发监控2.0。

团队在研究完Nagios、Cacti、Zabbix开源系统后,发现这些系统在扩展性方面,告警运维值班便捷性上满足不了我司的运维需求。

苗辉是当时的leader,这家伙就喜欢自己折腾个东西出来,而我当时心里挺犹豫,有开源的不用,为啥要从0到1自己搞。只是这个家伙"吹牛"还是可以的,把老板说服了,带着4~5个应届生,我们就开干了。单单设计文档我们就整了100多页,方案来回讨论了有1个月,团队苦逼的搞了大半年,alpha版本终于上线了。

监控restTemplate使用情况 监控平台 ui_运维_04

架构说明:

  • wsmsagent——wsMS的数据收集接口;
  • MI——wsMS的数据中转加工站;
  • AL——wsMS的告警分析;
  • RRDS——wsMS的监控数据绘图引擎;
  • SCHEDULER——wsMS自动均衡的决策中心;
  • SCADA——wsMS的通用采集监测组件;
  • UI——展示界面。

监控3.0

这个系统线上运营了2年,2011年随着机器规模迅速增加到7K+,平台开始爆发出各种问题:

  • 机器增加到2万的时候,监控数据单表1天超过5亿条数据,复杂的SQL告警规则查询耗时太长;
  • 原始告警移到历史告警通过Insert和Delete,性能太低;
  • 通过数据持久化再分析生成告警,已经满足不了实时性的要求;
  • 复杂的告警规则通过SQL已经无法支持;
  • 新增一种采集类型的数据,都需要二次开发,成本较高;
  • 每天有2W+的告警,运维根本处理不过来;
  • 监控和告警数据很多,为什么还是有不少故障监控没有发现?

这个时候苗辉跑去百度了,我一个人压力山大。当时外部对监控不是很满意,告警刷屏时有发生。

2015年底我决定搞监控3.0,以构建立体化的监控体系为目标,将告警分层,覆盖从基础设施->组件->产品服务->客户业务的四层告警。自上而下做告警定位,由下而上确定告警影响范围。建立告警间的相互关联关系,当出现一个严重级别的告警时,能展示告警的影响范围。

架构图


监控restTemplate使用情况 监控平台 ui_数据_05

调度系统


监控restTemplate使用情况 监控平台 ui_数据_06

UI层:提供任务类型配置、任务分配结果查询,任务状态查询,组件状态查。2)由UI-master,UI-slave组成,利用LVS或NGNIX做主从。

任务调度层:根据原始任务状态,监控机状态,任务配置状态决策是否进行任务分配,通过zeroMQ向任务分配层发送分配任务2)同时定时向任务加载层发送任务加载任务3)有core-master,core-slave组成,利用zk或hzelcast做主从。

任务加载层:负责接收Core-master的加载任务,向外部系统获取原始任务,写入mysql

任务分配层:负责接收Core-master的分配任务,执行分配策略,将数据写入memcache

数据缓存层:memcahe缓存任务分配结果,cachedump定时将分配结果快照写入mysql

任务分发层:负责接收scada或其他采集客户端的请求,将任务分发给采集端

ZeroMQ:zeroMQ,消息队列,可自动实现负载均衡

Monitor:负责调度平台可视化数据维护,包含各组件的运行状态,任务加载,调度,分配,分发状态

ZK/hazelcast:分布式协调系统,用于core组件进行主备选举,机房内部署集群,设置iptable只允许同机房访问。

告警决策


监控restTemplate使用情况 监控平台 ui_运维_07

NodeCluster

消息生产集群,接入不同的数据源类型,生产待计算的原始消息。如接收sdn推送的监控采集数据,以每一行为一条计算数据提交。

MessageCluster

使用kafka消息中间件,暂存计算消息。实现数据的流式输入。

JstormCluster

核心计算集群,基于storm的java版本,改进HA问题和计算性能优化。

MonitorCluster

集群状态监控,负责进行集群内部的组件状态、topology计算状态的监控报警

ThorUI

UI作为实时计算平台的运营界面,主要任务是各个组件的运行状态收集、消息任务配置、监控报警展示、系统配置等。

数据库性能调优

在监控2.0阶段,监控数据是存储在MySQL,监控数据每天达到750G+,单表每天数据量10亿条,数据查询非常慢。我们对监控表做读写分离和水平分表看下测试的效果,但测试的结果让我们大失所望。

监控restTemplate使用情况 监控平台 ui_数据_08

  • 读写分离和单实例的查询和更新响应时间没有太大的区别;
  • 通过mycat的水平分表,在大量数据下有优势,但小量数据则无优势。所谓大量数据,表内数据最好在千万级别以上,插入量最好在百万级别以上。

上述两个方案行不通,我们决定采用第3种方案,表分区方案。即以5分钟为一分区,根据每个监控对象实际需求创建分区数,由crontab脚本定时执行,执行时根据总时长、监控数据保留时长、当前时间,数据计算出要删除的分区,truncate分区数据。表分区方案将delete和load、select隔离在不同分区,减少delete对load、select的影响。通过一段时间的测试,发现测试效果还是不错的,比之前有一定幅度的提升。

监控restTemplate使用情况 监控平台 ui_数据_09

如何基于开源快速搭建一个监控系统

1.zabbix

如果你的公司机器规模少于1000台,没有用到K8S,告警逻辑也不复杂,那推荐你用zabbix,基本能满足企业内部普通的IT运维。

监控restTemplate使用情况 监控平台 ui_监控ui_10


2.Prometheus+Clickhouse

如果你的公司机器规模大于5000台,并且是通过容器化编排部署,告警逻辑也较为复杂,推荐Prometheus+Clickhouse。可参考之前的文章。

监控restTemplate使用情况 监控平台 ui_监控ui_11


3.Prometheus+Telegraf+influxdb

Telegraf是实现数据采集的工具。Telegraf 具有内存占用小的特点,通过插件系统开发人员可轻松添加支持其他服务的扩展。在平台监控系统中,可以使用 Telegraf 采集多种组件的运行信息,而不需要自己手写脚本定时采集,大大降低数据获取的难度。

监控restTemplate使用情况 监控平台 ui_监控restTemplate使用情况_12

总结

最后,我总结出来做好监控很重要的4个点:

  • 一定要建立体系化的监控告警平台,确定监控scope,避免成为“背锅侠”。
  • 监控不只是运维的事,研发设计要把组件监控纳入进来。
  • 监控越往前做越有效,等到组件上线运营后再补充的代价是极高的。
  • 监控发展的必经之路,少->全->精,要避免告警风暴,做到精准。