之前写过几篇关于在线排错的文章,文中附上了一些监控图片。有读者对此很感兴趣,问我在监控系统选型方面有什么好的建议吗?图片来自Pexels。我体验过的几家公司的监控系统都是自研的。其实业界有很多优秀的开源产品可以选择,可以满足大部分的监控需求。如果能够选择一种满足企业当前的需求,显然是最省时省力的。在本文中,我将对监控系统的基础知识、原理、架构进行系统梳理。同时,我也会介绍几款最常用的开源监控产品,供大家选型时参考。内容包括以下三个部分:必知的监控基础知识主流监控系统介绍监控系统选型建议必知的监控基础知识监控系统俗称“第三只眼”,它们是我们几乎每天都在打交道的系统,我觉得以下四个基本知识是必须了解的。监控系统的7大功能正所谓“无监控,不运维”,监控系统的状态不言而喻。无论你是监控系统的开发者还是用户,首先要明确:监控系统的目标是什么?它能起到什么作用?监控系统具有以下七大功能:实时采集监控数据:包括硬件、操作系统、文件、应用程序等各个维度的中间数据。实时反馈监控状态:通过对采集到的数据进行多维度的统计和可视化展示,实时反映监控对象的状态是正常还是异常。预知故障与预警:可提前预知故障风险,及时发布预警信息。辅助故障定位:提供故障发生时的各种指标数据,辅助故障分析定位。辅助性能调优:为性能调优提供数据支持,如慢SQL、接口响应时间等。辅助容量规划:为服务器、中间件、应用集群的容量规划提供数据支持。辅助自动化运维:根据配置的SLA,为自动扩容或服务降级等智能运维提供数据支持。如果说监控系统的使用姿势不对造成线上事故,别说是其他地方的问题,就一定是监控部分有问题。听着很刺耳的一句话,仔细想想好像也有道理。我们在回顾事故时,通常会思考这三个与监控相关的问题:有没有监控?监测是否及时?监控信息是否有助于快速定位问题?可见光光有一个好的监控系统是不够的,还必须知道如何用好它。一个成熟的研发团队通常会制定一个监控规范来统一监控系统的使用。如何使用监控系统?总结如下四个方面:了解监控对象的工作原理:对监控对象有基本的了解,了解其工作原理。比如要监控JVM,就必须知道JVM的堆内存结构和垃圾回收机制。确定监控对象的指标:知道用哪些指标来描述监控对象的状态?比如你要监控某个接口,可以用请求量、耗时、超时量、异常量等指标来衡量。定义合理的报警阈值和级别:什么阈值需要报警?对应的故障等级是多少?不需要处理的告警不是好的告警。可见定义一个合理的阈值是多么的重要,否则只会降低运维效率或者让监控系统失去作用。建立完整的故障处理流程:接到故障告警后,必须有相应的处理流程和oncall机制,以便及时跟进故??障。监控什么监控对象,监控什么指标,已经成为整个产品生命周期中非常重要的一环。运维侧重于硬件和基础监控,研发侧重于各中间件和应用层的监控,产品侧重于核心业务指标的监控。可以看到监控的对象越来越立体化了。在这里,我将常用的监控对象和监控指标进行了分类,供大家参考:①硬件监控包括:电源状态、CPU状态、机器温度、风扇状态、物理磁盘、raid状态、内存状态、网卡状态。②服务器基础监控包括:CPU:单CPU和整体使用情况。内存:已用内存、可用内存。磁盘:磁盘使用率、磁盘读写吞吐量。网络:出口流量、入口流量、TCP连接状态。③数据库监控包括:数据库连接数、QPS、TPS、并行处理会话数、缓存命中率、主从延迟、锁状态、慢查询。④中间件监控包括:Nginx:活跃连接数、等待连接数、丢弃连接数、请求量、耗时、5XX错误率。Tomcat:最大线程数、当前线程数、请求量、耗时、错误量、堆内存占用、GC次数和耗时。缓存:成功连接数、阻塞连接数、已用内存、内存碎片率、请求量、耗时、缓存命中率。消息队列:连接数、队列数、生产率、消费率、消息堆积。⑤应用监控包括:HTTP接口:URL存活、请求量、耗时量、异常量。RPC接口:请求量、耗时量、超时量、拒绝量。JVM:GC次数、GC耗时、各内存区大小、当前线程数、死锁线程数。线程池:活跃线程数、任务队列大小、任务执行耗时、拒绝任务数。连接池:连接总数,活跃连接数。日志监控:访问日志、错误日志。业务指标:取决于业务,如PV、订单量等。监控系统的基本流程无论是开源监控系统还是自研监控系统,整个监控流程都是类似的。一般包括以下几个模块:数据采集:采集数据的方式有很多种,包括日志采集(通过Logstash、Filebeat等进行上报分析)、JMX标准接口输出监控指标、监控对象为数据提供RESTAPI采集(如Hadoop、ES)、系统命令行、统一SDK侵入式埋点上报等。数据传输:将采集到的数据以TCP、UDP或HTTP协议的形式上报给监控系统。有主动Push模式和被动Pull模式。数据存储:有的使用MySQL、Oracle等RDBMS进行存储,有的使用时序数据库RRDTool、OpentTSDB、InfluxDB进行存储,有的使用HBase进行存储。数据显示:数据指标图形化显示。监控告警:告警设置灵活,支持Email、SMS、IM等多种通知渠道。主流监控系统介绍让我们来认识一下主流的开源监控系统。由于篇幅有限,我选取了目前使用最广泛的三个监控系统:Zabbix、Open-Falcon和Prometheus。我将介绍它们的体系结构并总结它们各自的优缺点。Zabbix(老式监控的优秀代表)Zabbix诞生于1998年,核心组件采用C语言开发,Web端采用PHP开发。是旧监控系统的优秀代表。监控功能全面,应用广泛。几乎70%的互联网公司都使用Zabbix作为监控解决方案。我们先了解下Zabbix的架构设计:Zabbix架构图如上:ZabbixServer:核心组件,用C语言编写,负责接收Agent和Proxy发送的监控数据,也支持JMX、SNMP等协议直接采集数据。同时还负责数据的汇总存储和告警触发。ZabbixProxy:一个可选组件。对于大量被监控的机器,可以使用Proxy进行分布式监控。可以代Server采集部分监控数据,减轻Server的压力。ZabbixAgentd:部署在被监控主机上,用于收集本地数据,发送给Proxy或Server。其插件机制支持用户自定义数据采集脚本。Agent可以在Server端手动配置,也可以通过自动发现机制来识别。数据采集??方式支持主动Push和被动Pull两种方式。数据库:用于存储配置信息和收集的数据,支持MySQL、Oracle等关系型数据库。同时最新版本的Zabbix已经开始支持时序数据库,但成熟度还不高。WebServer:Zabbix的GUI组件,用PHP编写,提供监控数据展示和告警配置。Zabbix的优势如下:成熟的产品:由于历史悠久,用途广泛,拥有丰富的文档和各种开源的数据采集插件,可以覆盖大部分监控场景。采集方式丰富:支持Agent、SNMP、JMX、SSH等多种采集方式,支持主动和被动数据传输方式。扩展性强:支持Proxy分布式监控,Agent自动发现功能,插件式架构支持用户自定义数据采集脚本。便捷的配置管理:可通过Web界面进行监控和告警配置,操作简单,使用方便。Zabbix的缺点如下:性能瓶颈:机器量大或者业务量大之后,关系型数据库的写入肯定是瓶颈。官方单机上限是5000台,个人达不到,尤其是现在应用层指标越来越多。虽然最新版本已经开始支持时序数据库,但是成熟度不高。应用层监控支持有限:如果想对应用做侵入式的埋点和采集(比如监控线程池或者接口性能),Zabbix没有提供相应的SDK,也可以通过插件脚本实现该功能。个人感觉Zabbix不适合这个。数据模型不强大:不支持标签,无法进行多维度聚合统计和告警配置,使用不灵活。二次开发难:Zabbix使用C语言,二次开发往往需要熟悉其数据表结构。基于它提供的API,更多只能针对展示层进行定制。Open-Falcon(小米出品,国内流行)Open-falcon是小米公司于2015年开发的开源企业级监控工具,使用Go和Python开发。、美团、滴滴等200多家企业在使用。小米早期也用Zabbix做监控,但是随着机器量和业务量的增加,Zabbix就有点力不从心了。所以后来独立开发了Open-Falcon,借鉴了Zabbix在架构设计上的经验,同时解决了Zabbix的很多痛点。先来了解一下Open-Falcon的架构设计:Open-Falcon的架构图如上:Falcon-agent:数据采集器和采集器,Go开发,部署在被监控机器上,支持3种数据采集方式。首先,无需任何配置即可自动采集单机200多项基础监控指标;同时支持自定义Plugin获取监控数据;另外,用户可以通过HTTP接口独立推送数据到本机的proxy-gateway,由Gateway转发到Server。Transfer:数据分发组件接收客户端发送的数据,分别发送给数据存储组件Graph和告警判定组件Judge。Graph和Judge都使用一致的Hash进行数据分片,以提高水平扩展能力。同时Transfer还支持将数据分发到OpenTSDB进行历史归档。Graph:数据存储组件,底层使用RRDTool(时间序列数据库)存储单个指标,并通过缓存和批量写入磁盘进行优化。据说一个Graph实例可以处理每秒8W+的写入速率。JudgeandAlarm:报警元件。Judge实时计算Transfer组件上报的数据,判断是否产生告警事件。Alarm组件收敛告警事件后,将告警消息推送到各个消息通道。API:对于终端用户来说,在收到查询请求后,会查询Graph中的指标数据,并将结果汇??总后返回给用户,屏蔽了存储集群分片的细节。以下是Open-Falcon的优势:自动采集能力:Falcon-agent可以自动采集服务器200多项基础指标(如CPU、内存等),服务器无需任何配置,可秒杀Zabbix很快。强大的存储能力:底层使用RRDTool,通过一致性Hash进行数据分片,构建可扩展性强的分布式时序数据存储系统。灵活的数据模型:参考OpenTSDB,在数据模型中引入Tag,可以支持多维度的聚合统计和告警规则设置,大大提高了使用效率。插件统一管理:Open-Falcon的插件机制实现了用户自定义脚本的统一管理,可以通过HeartBeatServer分发给Agent,降低用户自行维护脚本的成本。个性化监控支持:基于Proxy-gateway,通过自埋点轻松实现应用层监控(如监控接口访问、耗时等)等个性化监控需求,集成方便。以下是Open-Falcon的不足之处:整体发展一般:社区活跃度不高,版本更新慢。一些大厂直接基于其稳定版进行二次开发。我其实有点担心未来的前景。UI不够友好:对于业务线的研发,可能只想方便的完成告警配置和业务监控,但它把机器分组、策略模板、模板继承等所有概念都暴露在了UI上,而且感觉围绕这些概念设计UI有点难懂。安装比较复杂:个人经验,因为是从小米内部系统衍生出来的,虽然去掉了对小米内部系统的依赖,但是组件还是比较多的。如果不熟悉整个架构,很难一蹴而就。Prometheus(被誉为下一代监控系统)Prometheus(普罗米修斯)是前谷歌员工于2015年正式发布的开源监控系统,采用Go语言开发。它不仅名字很酷,而且有Google和K8s的大力支持,开源社区异常火爆。Prometheus于2016年加入CloudNativeFoundation,是继K8s之后托管的第二个项目,未来前景相当可观。它和Open-Falcon最大的区别在于数据采集是基于Pull模式而不是Push模式,架构非常简单。我们先来了解一下Prometheus的架构设计:Prometheus的架构图如上:PrometheusServer:核心组件,用于采集和存储监控数据。既支持静态配置,也支持通过ServiceDiscovery进行动态发现,实现对监控目标的管理和获取监控目标的数据。此外,PrometheusServer也是一个时序数据库,将监控数据保存在本地磁盘,并提供自定义的PromQL语言来查询和分析数据。Exporter:用于收集数据,类似于Agent,不同的是Prometheus是基于Pull方式拉取和收集数据。因此Exporter通过HTTP服务将监控数据以标准格式暴露给PrometheusServer。社区中已经有大量现成的Exporter可以直接使用,用户也可以使用各种语言的客户端库的自定义实现。Pushgateway:主要用于瞬态任务场景,防止PrometheusServer拉取数据之前执行此类短命作业。因此Job可以主动将监控数据以Push的形式上报给Push网关缓存起来中转。AlertManager:当有告警产生时,PrometheusServer将告警信息推送给AlertManager,AlertManager将告警信息发送给接收者。WebUI:Prometheus内置了一个简单的web控制台,可以查询配置信息和指标等。在实际应用中,我们通常使用Prometheus作为Grafana的数据源来创建仪表盘和查看指标。Prometheus的优点如下:轻量级管理:架构简单,独立于外部存储,单个服务器节点可以直接工作,只需启动二进制文件,是一个轻量级服务器,易于迁移和维护。处理能力强:监控数据直接存储在PrometheusServer本地时序数据库中,单实例可处理百万级指标。数据模型灵活:与Open-Falcon类似,引入Tag,属于多维数据模型,聚合统计更方便。强大的查询语句:PromQL允许在同一个查询语句中对多个Metrics进行加法、连接、分位数等操作。对云环境的支持很好:可以自动发现容器,K8s、Etcd等项目原生支持Prometheus,是目前最流行的容器监控方案。以下是Prometheus的不足:功能不足:Prometheus从一开始的架构设计就是简单,没有提供集群方案,长期持久化存储和用户管理,这些都是企业做大的必备功能.目前这些只能在Prometheus之上进行扩展。网络规划变得复杂:由于Prometheus采用Pull模型拉取数据,这就意味着所有被监控的Endpoint都必须可达,需要规划好网络的安全配置。监控系统选型建议通过上面的介绍,大家应该对主流的监控系统有了一定的了解。面对选型问题,我的建议是:首先明确你的监控需求:监控的对象是什么?有多少台机器和监控指标?您需要什么样的报警功能?监控是一项长期建设,我一开始就想做一个AllInOne的监控方案,但是我觉得没必要。从成本上来说,前期直接使用开源的监控方案就可以了,先解决问题。从系统成熟度来看,Zabbix是老牌的监控系统,数据量大,功能全面稳定。如果机器数量在几百台以内,就不用太担心性能问题。此外,它采用数据库分区、SSD硬盘、Proxy架构、Push两种采集方式,可以提高监控性能。Zabbix在服务器监控上有绝对的优势,可以满足90%以上的监控场景,但是应用层的监控好像不太擅长,比如监控线程池的状态,执行时间内部接口等,通常需要进行侵入式掩埋。相反,新一代的监控系统Open-Falcon和Prometheus在这一点上做得很好。从整体性能来看,新一代监控系统也具有明显优势,如:灵活的数据模型、更成熟的时序数据库、强大的告警功能等。如果之前对Zabbix等传统监控没有技术积累,建议使用Open-Falcon或者Prometheus。Open-Falcon的核心优势在于数据分片功能,可以支持更多的机器和监控项;Prometheus是容器监控的标准配置,Google和K8s都支持。Zabbix、Open-Falcon和Prometheus都支持与Grafana的快速集成。如果你想要一个漂亮而强大的可视化体验,你可以将它与Grafana结合起来。使用合适的监控系统就可以解决相应的问题,而且可以同时使用多套监控,这在企业早期是很常见的。中后期,随着机器数据的增加和个人需求的增加(比如希望统一监控平台,打通公司CMDB和组织架构的关系),通过API进行二次开发或集成通常需要由监控系统提供。从这个角度看,Open-Falcon或者Prometheus更合适。如果非要自己研究,可以研究一下主流监控系统的架构方案,学习它们的优点。最后,本文详细梳理了监控系统的基础知识、原理和主流架构,希望能帮助大家了解监控系统,在选择技术时做出更合适的选择。由于篇幅问题,本文内容不涉及全链路监控、日志监控、web前端和客户端监控。可见,监控确实是一个庞大而复杂的系统。要想理解透彻,就必须理论联系实际。深的。对于运维监控系统,如果大家也有自己的体会和心得,欢迎留言讨论。作者:罗君武简介:前亚马逊工程师,现58转转技术总监,持续分享个人成长经验,希望能为你的职业发展带来一些新思路。编辑:陶佳龙来源:转载自微信公众号IT人的职场进阶
