如何自己实现监控告警系统
监控系统俗称「第三只眼」,几乎是我们每天都会打交道的系统,那么如何开发一块适合自己公司的监控呢?
监控系统的作用
正所谓「无监控,不运维」,监控系统的地位不言而喻。不管你是监控系统的开发者还是使用者,首先肯定要清楚:监控系统的目标是什么?它能发挥什么作用?
- 实时采集监控数据:包括硬件、操作系统、中间件、应用程序等各个维度的数据。
- 实时反馈监控状态:通过对采集的数据进行多维度统计和可视化展示,能实时体现监控对象的状态是正常还是异常。
- 预知故障和告警:能够提前预知故障风险,并及时发出告警信息。
- 辅助定位故障:提供故障发生时的各项指标数据,辅助故障分析和定位。
- 辅助性能调优:为性能调优提供数据支持,比如慢SQL,接口响应时间等。
- 辅助容量规划:为服务器、中间件以及应用集群的容量规划提供数据支撑。
- 辅助自动化运维:为自动扩容或者根据配置的SLA进行服务降级等智能运维提供数据支撑。
使用监控系统的正确姿势
出任何线上事故,先不说其它地方有问题,监控部分一定是有问题的。
听着很甩锅的一句话,仔细思考好像有一定道理。我们在事故复盘时,通常会思考这3个和监控有关的问题:有没有做监控?监控是否及时?监控信息是否有助于快速定位问题?
可见光有一套好的监控系统还不够,还必须知道「如何用好它」。一个成熟的研发团队通常会定一个监控规范,用来统一监控系统的使用方法。
- 了解监控对象的工作原理:要做到对监控对象有基本的了解,清楚它的工作原理。比如想对JVM进行监控,你必须清楚JVM的堆内存结构和垃圾回收机制。
- 确定监控对象的指标:清楚使用哪些指标来刻画监控对象的状态?比如想对某个接口进行监控,可以采用请求量、耗时、超时量、异常量等指标来衡量。
- 定义合理的报警阈值和等级:达到什么阈值需要告警?对应的故障等级是多少?不需要处理的告警不是好告警,可见定义合理的阈值有多重要,否则只会降低运维效率或者让监控系统失去它的作用。
- 建立完善的故障处理流程:收到故障告警后,一定要有相应的处理流程和oncall机制,让故障及时被跟进处理。
监控的对象和指标都有哪些?
监控已然成为了整个产品生命周期非常重要的一环,运维关注硬件和基础监控,研发关注各类中间件和应用层的监控,产品关注核心业务指标的监控。可见,监控的对象已经越来越立体化。
硬件监控
包括:电源状态、CPU状态、机器温度、风扇状态、物理磁盘、raid状态、内存状态、网卡状态
服务器基础监控
CPU:单个CPU以及整体的使用情况 内存:已用内存、可用内存 磁盘:磁盘使用率、磁盘读写的吞吐量 网络:出口流量、入口流量、TCP连接状态
数据库监控
包括:数据库连接数、QPS、TPS、并行处理的会话数、缓存命中率、主从延时、锁状态、慢查询
中间件监控
Nginx:活跃连接数、等待连接数、丢弃连接数、请求量、耗时、5XX错误率 Tomcat:最大线程数、当前线程数、请求量、耗时、错误量、堆内存使用情况、GC次数和耗时 缓存 :成功连接数、阻塞连接数、已使用内存、内存碎片率、请求量、耗时、缓存命中率 消息队列:连接数、队列数、生产速率、消费速率、消息堆积量
应用监控
HTTP接口:URL存活、请求量、耗时、异常量 RPC接口:请求量、耗时、超时量、拒绝量 JVM :GC次数、GC耗时、各个内存区域的大小、当前线程数、死锁线程数 线程池:活跃线程数、任务队列大小、任务执行耗时、拒绝任务数 连接池:总连接数、活跃连接数 日志监控:访问日志、错误日志 业务指标:视业务来定,比如PV、订单量等
监控系统的基本流程
无论是开源的监控系统还是自研的监控系统,监控的整个流程大同小异,一般都包括以下模块:
- 数据采集:采集的方式有很多种,包括日志埋点进行采集(通过Logstash、Filebeat等进行上报和解析),JMX标准接口输出监控指标,被监控对象提供REST API进行数据采集(如Hadoop、ES),系统命令行,统一的SDK进行侵入式的埋点和上报等。
- 数据传输:将采集的数据以TCP、UDP或者HTTP协议的形式上报给监控系统,有主动Push模式,也有被动Pull模式。
- 数据存储:有使用MySQL、Oracle等RDBMS存储的,也有使用时序数据库RRDTool、OpentTSDB、InfluxDB存储的,还有使用HBase存储的。
- 数据展示:数据指标的图形化展示。
- 监控告警:灵活的告警设置,以及支持邮件、短信、IM等多种通知通道。
主流监控系统介绍
Zabbix
Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。Zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供强大的通知机制以让系统运维人员快速定位/解决存在的各种问题。
Prometheus
Prometheus是一套开源的系统监控报警框架,它既适用于面向服务器等硬件指标的监控,也适用于高动态的面向服务架构的监控。对于现在流行的微服务,Prometheus的多维度数据收集和数据筛选查询语言也是非常的强大。Prometheus是为服务的可靠性而设计的,当服务出现故障时,它可以使你快速定位和诊断问题。
Nightingale
Nightingale(夜莺)是滴滴基础平台联合滴滴云研发和开源的企业级监控解决方案。旨在满足云原生时代企业级的监控需求。Nightingale 在产品完成度、系统高可用、以及用户体验方面,达到了企业级的要求,可满足不同规模用户的场景,小到几台机器,大到数十万都可以完美支撑。兼顾云原生和裸金属,支持应用监控和系统监控,插件机制灵活,插件丰富完善,具有高度的灵活性和可扩展性。
自己设计监控
数据采集(collector): 通过SNMP、Agent、ICMP、SSH、IPMI等协议对系统进行数据采集。
数据存储(storage):主要存储在MySQL上,也可以存储在其他数据库服务。
数据分析(engine):当事后需要复盘分析故障时,监控系统能给我们提供图形和时间等相关信息,方面确定故障所在。
数据展示(view):Web界面展示(移动APP、java_php开发一个web界面也可以)。
监控报警(alert Manager):电话报警、邮件报警、微信报警、短信报警、报警升级机制等(无论什么报警都可以)。
报警处理:当接收到报警,我们需要根据故障的级别进行处理,比如:重要紧急、重要不紧急等。根据故障的级别,配合相关的人员进行快速处理。
采集监控数据
系统采用定时拉取的模式,设计定时拉取的Job,按照一定时间执行,定时任务使用Xxl-job。
/**
* 消息告警定时任务
*/
@Component
@JobHandler(value = "alertJob")
@Slf4j
public class AlertJob extends IJobHandler {
@Autowired
private AlertProcessorService alertProcessorService;
@Resource
private CollectorService collectorService;
/**
* 执行规则表达式,将命中的告警信息发送到manager
*/
@Override
public ReturnT<String> execute(String s) throws Exception {
AppMonitor.biz("alert");
StopWatchUtils.stopWatch("自定义监控告警", "从多种来源进行监控告警", () -> alertProcessorService.process(collectorService.collect()));
return ReturnT.SUCCESS;
}
}
监控数据采集使用统一的接口,现在接入设计如下:
/**
* 对告警信息进行采集
*/
public interface CollectService {
/**
* 数据来源
* @return
*/
String getSource();
List<MetricData> collect();
}
接口关键信息
- getSource 接口采集数据来源,目前支持Prometheus和Skywalking
- collect 采集接口数据,并将数据转化为List
指标信息
定义合理的报警阈值和等级
用户需要在页面定义合理的报警阈值和等级, 用户在前台页面配置合理的告警表达式,目前Skywalking主要支持表达式为告警异常信息。 Prometheus支持配置PromQL查询语句。系统采集到的数据会通过规则表达式进行计算。 如果需要告警,则会依次执行告警执行器
告警执行器
告警执行器,支持多种告警信息策略, 如下所示: SilencesProcessService: 静默执行器,如果apollo配置isSilences,则不再发送告警信息。 InhibitionProcessService: 告警消息抑制:同一个告警信息取时间最小的那条 同一个应用,同一个告警错误信息 GroupWaitProcessService: 告警分组等待,对于同一个告警信息,则间隔某段时间之后再告警 TraceIdProcessorService: 根因分析,目前支持按照TraceId分析告警错误信息。
消息发送执行器 MessageBuildProcessService 构建告警信息 MessageDingTalkProcessService 钉钉发送告警信息 MessageOrderProcessService 钉钉工单生成。 MessageTemplateProcessService 组装消息的模板信息。 MetricDataSaveProcessService 持久化告警信息