监控之美——监控系统选型分析及误区探讨
本文摘自于朱政科撰写的《Prometheus 云原生监控:运维与开发实战》,重点介绍了在监控系统选型中应该考虑的问题。
上一篇“监控之美——Prometheus云原生监控”介绍了云原生监控的原理,在本文中,你将会了解监控应用程序的黑盒和白盒方法,也会了解监控执行检查的拉取和推送方式,还会了解常见的监控系统以及进行监控系统选型时应该注意的问题。
1 黑盒监控和白盒监控
《SRE: Google 运维解密》一书中指出,监控系统需要有效支持白盒监控和黑盒监控;还有一种类似的观点认为,监控系统必须支持探针(Probing)和内省(Introspection)。
黑盒监控,对应探针的概念,常见的有 HTTP 探针、TCP 探针等,可以在系统或者服务发生故障时快速通知相关人员进行处理。探针位于应用程序的外部,通过监听端口是否有响应且返回正确的数据或状态码等外部特征来监控应用程序。Nagios 就是一个主要基于黑盒/探针的监控系统。
白盒监控,对应内省的概念,通过白盒能够了解监控对象内部的实际运行状态,通过对监控指标的观察能够预判可能出现的问题,从而对潜在的不确定因素进行优化。白盒监控可以直接将事件、日志和指标发送到监控工具,它具有比黑盒监控更丰富的应用程序上下文信息。MDD 理念主要对应的就是基于白盒的监控系统。
2 监控检查的两种模式—拉取和推送
监控系统执行监控检查的模式主要有拉取(Pull)和推送(Push)两种。这两种模式究竟哪种更好?对此,监控领域内部存在相当大的争议。
拉取模式(简称拉模式),是一种从监控对象中通过轮询获取监控信息的方式。拉模式更多拉取的是采样值或者统计值,由于有拉取间隔,因此并不能准确获取数值状态的变化,只能看到拉取间隔内的变化,因此可能会产生一些毛刺现象,需要进一步进行数据处理。监控和性能测试更关注 p95/p99 位的原因就是存在长尾效应。数据采集过程中对数据进行的定义、采样、去尖刺等处理操作也是非常重要的,这部分内容我们会在后续章节详细介绍。
拉模式的优点是告警可以按照策略分片,告警模块只需要拉取自己需要的数据,且可以完美支持聚合场景;拉模式的缺点在于监控数据体量非常庞大,对存储有较高的要求,实战中可能还需要考虑数据的冷热分离。
推送模式(简称推模式),是应用程序基于事件主动将数据推向监控系统的方式。推模式的优点是实时性好,一旦触发一个事件就可以立刻收集发送信息。但是推模式的缺点也很明显,由于事件的不可预知性,大量的数据推送到监控系统,解析和暂存会消耗大量的内存,这可能对监控的进程产生影响。由于消息是推送过来的,所以主动权在推送方。在这种模式下,由于网络等迟迟没有得到确认,所以在 ack 等情况下很容易造成数据重复。这是因为推模式在进行推送中,如果发送失败,为了防止内存撑爆,系统会将数据持久化到文件或者队列。因此采用推模式时,若产生了重复数据,就需要进行去重等操作,对于这些技术细节,需要仔细打磨。
Prometheus 在收集数据时,主要采用拉模式(服务端主动去客户端拉取数据),当然它也支持接收推送到 Pushgateway 的事件;而以 Zabbix 为代表的传统监控系统采用推模式(客户端发送数据给服务端)。
拉模式在云原生环境中有比较大的优势,原因是在分布式系统中,一定是有中心节点知道整个集群信息的,那么通过中心节点就可以完成对所有要监控节点的服务发现,此时直接去拉取需要的数据就好了;
推模式虽然可以省去服务发现的步骤,但每个被监控的服务都需要内置客户端,还需要配置监控服务端的信息,这无形中加大了部署的难度。推模式在 OpenStack 和 Kubernetes 等环境中使用比较少。
3 5 种常见的监控系统
有些技术人员常说:“我刚接触监控的时候就已经是 Prometheus 的时代了,我都没有接触过 Nagios、Zabbix 这些上古监控系统。”那么,在 Prometheus 之前,常见监控系统都是怎样的呢?让我们一起来了解一下。
3.1 Nagios
Nagios 原名 NetSaint,是 Nagios Ain’t Gonna Insist On Sainthood 的缩写,Sainthood 译为圣徒,而 Agios 是 saint 希腊语的表示方法。它是由 Ethan Galstad 开发并维护的一款开源且老牌的监控工具,用 C 语言编写而成。Nagios 虽然开发时被定义为在 Linux 下使用,但在 UNIX 下也工作得非常好。
在涉及开源监控时,Nagios 会被一些人认为是“行业标准”,这在某种程度上是正确的,因为 Nagios 是第一个真正称得上专业的监控系统。在 Nagios 之前,虽然也有一些监控工具,但是这些工具都太“业余”了,以至于它们根本无法与 1999 年推出的 Nagios 相提并论。Nagios 是监控领域的第一个跨时代产品,且拥有最大的社区和非常多的 Fork,如 OpsView、OP5、Centreon、Icinga、Naemon、Shinken 等。有过多的 Fork,意味着在应用插件或工具时会造成混乱,因为每个分支都有不同的理念,随着时间的推移,这使得 Nagios 与其他分支、父项目(Nagios)出现不兼容的现象。
Nagios 能有效监控 Windows、Linux 和 UNIX 的主机状态(CPU、内存、磁盘等),以及交换机、路由器等网络设备(SMTP、POP3、HTTP 和 NNTP 等),还有 Server、Application、Logging,用户可自定义监控脚本实现对上述对象的监控。Nagios 同时提供了一个可选的基于浏览器的 Web 界面,以方便系统管理人员查看网络状态、各种系统问题以及日志等。
如图 1-8 所示,Nagios 的核心架构主要由 Nagios Daemon、Nagios Plugins 和 NRPE 这 3 个模块构成。
由图 1-8 可知:
Nagios Daemon 作为系统的核心组件,负责组织与管理各组件,协调它们共同完成监控任务,并负责监控信息的组织与展示。
Nagios Plugins 主要指 Nagios 核心组件自带的组件,还包括一些用户自开发的插件。这些组件监控各项指标,并将采集到的数据回送给 Nagios 服务器。
NRPE(Nagios Remote Plugin Executor)是安装在监控主机客户端上的代理程序(Linux 系统是 NRPE 软件)。通过 NRPE 可获取监控数据,这些数据会被再回送给 Nagios 服务器。默认使用的端口是 5666。
Nagios 以监控服务和主机为主,但是它本身不包括这部分功能,是通过“插件”生态系统或第三方功能来实现的。在主动模式中,Nagios 不需要调用客户端的插件,而是通过自己的插件主动探测客户端的相关信息;在被动模式中,Nagios 通过启动客户端上的 NRPE 来远端管理服务。启动 Nagios 后,它会周期性自动调用插件以检测服务器状态,同时会维持一个队列,所有插件返回的状态信息都会进入该队列,Nagios 每次都会从队首读取信息,处理后再将状态结果呈现出来。被动模式的具体流程如下(见图 1-9)。
Nagios 执行安装在它里面的 check_nrpe 插件,并告诉 check_nrpe 检测哪些服务。
通过 SSL, check_nrpe 连接远端机器上的 NRPE Daemon。
NRPE 运行本地的各种插件来检测本地的服务和状态。
NRPE 把检测结果传给主机端 check_nrpe, check_nrpe 再把结果送到 Nagios 状态队列中。
Nagios 依次读取队列中的信息,再把结果显示出来。
Nagios 会将获取的数据保存在环形数据库(Round Robin Database,RDD)中。RDD 是一种循环使用存储空间的数据库,适用于存储和时间序列相关的数据。RDD 数据库在创建的时候就会定义好大小并使数据存储空间形成圆环状,每个数据库文件都以.rdd 为后缀,指针指向最新的数据位置并随着数据读写移动。如果没有获取到最新数据,RDD 就会使用默认的 unknown 填充空闲空间,以保证数据对齐。当空间存储满了以后,又从头开始覆盖旧的数据,所以和其他线性增长的数据库不同,RRD 的大小可控且不用维护。
Nagios 出现于 20 世纪 90 年代,它的思想仍然是通过复杂的交错文本文件、脚本和手动程序进行管理,基于文本文件的配置每次进行更改时都需要进行重置,这也使得在文件分布复杂的情况下必须借助第三方工具(例如 Chef 或 Puppet)进行部署,因此 Nagios 如何进行有效配置管理是一个瓶颈。为了使用 Nagios 监控,有必要熟练掌握处理数百个自定义脚本的方法,若这些脚本由不同的人采用不同的风格编写,那么处理脚本的过程几乎会变成某种“黑魔法”。对很多人来说,管理 Nagios 是非常复杂的,这最终导致 Nagios 成为软件与定制开发之间的奇怪组合。
Nagios(以及它的一些较新的分支,如 Naemon)仍然使用 C 编写的 CGI。这项技术是在 20 世纪 80 年代发明的,对其进行扩展或改进会很复杂,哪怕进行简单更改,都需要对整体架构代码打补丁并手动编译。Nagios 生态系统是基于每个 Fork 的不同版本的数百个不同补丁建立的,它简直就是一个集市,是“集市”模式的范例;而 Zabbix 和 Pandora FMS 则恰恰相反,是“大教堂”模式,是模块化的可靠项目,在架构师团队的指导下正在不断发展。
3.2 Zabbix
Zabbix 是一款拥有超过 21 年的历史、100%免费开源、全世界安装次数超过 30 万的监控软件(截至 2019 年),旨在从成千上万的服务器、虚拟机和网络设备中收集指标进行监控,是适用于绝大多数 IT 基础架构、服务、应用程序、云、资源等的解决方案。Zabbix 长期以来一直在瓜分 Nagios 的蛋糕,但它是一个成熟的系统,而不是简单的 Nagios 的分支,它的主要特征是对监控具有非常全面的视角,而不是仅仅监控状态,这恰是 Nagios 存在严重不足的地方。Zabbix 的配置文件也不像 Nagios 那么复杂。
Zabbix 是由 Alexei Vladishev 开源的分布式监控系统,和 Nagios 一样提供集中的 Web 管理界面。
Zabbix 有着非常酷炫的新版官网和详细的文档使用手册,企业级的 Zabbix 具有无限扩展、分布式监控、高可用、强大的安全性等特性。在本书截稿时,Zabbix 4.4 版本刚刚发布,这个版本用 Go 语言编写了全新的 Zabbix 代理,为 Zabbix 模板设置了标准,除了为 MySQL、PostgreSQL、Oracle、DB2 新增了 TimescaleDB 这种具有线性性能的数据库以外,还提供了高级可视化选项,以及一键式云部署等功能。
图 1-10 是 Zabbix 的架构图,Zabbix 可以通过 Agent 及 Proxy 的形式(见图 1-11),比如 JVM Agent、IPMI Agent、SNMP Agent 等采集主机性能、网络设备性能、数据库性能的相关数据,以及 FTP、SNMP、IPMI、JMX、Telnet、SSH 等通用协议的相关信息,采集信息会上传到 Zabbix 的服务端并存储在数据库中,相关人员通过 Web 管理界面就可查看报表、实时图形化数据、进行 7×24 小时集中监控、定制告警等。
3.3 Ganglia
Ganglia 直译为神经节、中枢神经,这一名称其实已经反映了作者的设计思路,即将服务器集群理解为生物神经系统,每台服务器都是独立工作的神经节,这些神经节通过多层次树突结构联结起来,既可以横向联合,也可以从低到高逐层传递信息。具体例证就是 Ganglia 的收集数据可以工作在单播(unicast)或多播(multicast)模式下(默认为多播模式)。很多通过 cacti 或者 Zabbix 看不出来的集群总体负载问题,都能在 Ganglia 中体现,其集群的熵图可以明确集群负载状况,这是 Ganglia 最大的亮点。
Ganglia 是加州大学伯克利分校发起的一个为 HPC(高性能计算)集群而设计的开源、可扩展、分布式监控系统,用于测量数以千计的节点。作者于 2000 年在伯克利分校网站上分享了源码。Ganglia 是 BSD 许可的开源项目,源于加利福尼亚大学的伯克利千年项目,最初是由美国国家高级计算基础设施合作伙伴(NPACI)和美国国家科学基金会 RI 奖 EIA-9802069 资助的。Ganglia 用于大规模的集群和分布式网格等高性能计算系统。基于 XML 技术的数据传递可以使系统的状态数据跨越不同的系统平台进行交互,且采用简洁紧凑的 XDR 方式实现监控数据的压缩和传输。它主要用于实时查看 Linux 服务器和集群(图形化展示)中的各项性能指标,让用户以集群(按服务器组)和网格(按地理位置)的方式更好地组织服务器。
Ganglia 的核心包含 gmond、gmetad 以及一个 Web 前端,其主要用来监控系统性能,如 CPU 使用率、硬盘利用率、I/O 负载、网络流量情况等,通过曲线很容易查看每个节点的工作状态,这对合理调整、分配系统资源,提高系统整体性能起到重要作用。Ganglia 与 Falcon、Zabbix 相比,主要区别体现在集群的状态集显示上,Ganglia 可以很便捷地对比各主机的性能状态。但随着服务、业务的多样化,Ganglia 表现出一些不足:覆盖的监控面有限,且自定义配置监控比较麻烦,在展示页面查找主机烦琐,展示图像粗糙且不精确。
如图 1-12 所示,Ganglia 通过 gmond 收集数据,数据传输到服务端 gmetad,最后在 PHP 编写的 Web UI 界面 Web 前端进行展示。组件之间通过 XDR(xml 的压缩格式)或者 XML 格式传递监控数据,以达到监控效果。
图 1-12 所示的各个模块介绍如下:
gmond(Ganglia Monitoring Daemon):双重角色,一方面作为 Agent 部署在需要监控的服务器上,另一方面作为收发机接收或转发数据包。可以将其理解为部署在每个监控服务器上的用于收集和发送度量数据的守护进程。
gmetad(Ganglia Meta Daemon):负责收集所在集群的数据并持久存储到 RRD 数据库,支持水平扩展。
Web 前端:Ganglia 项目提供了一个由 PHP 编写的通用型 Web 包,可以将主要实现数据可视化,并能提供一些简单的数据筛选 UI。页面不多,大量使用了模板技术。
Ganglia 的主要优势反映在收集数据和集中展示数据方面。Ganglia 可以将所有数据汇总到一个界面集中展示,并且支持多种数据接口,可以很方便地扩展监控,最为重要的是,Ganglia 收集数据非常轻量级,客户端的 gmond 程序基本不耗费系统资源,而这个特点刚好弥补了 Zabbix 的不足。gmond 带来的系统负载非常少,这使得它可以在集群中各台计算机上轻松运行,而不会影响用户性能。所有这些数据多次收集会影响节点性能。当大量小消息同时出现并造成网络“抖动”时,可以通过让节点时钟保持一致来避免这个问题。
Ganglia 对大数据平台的监控更为智能,只需要一个配置文件,即可开通 Ganglia 对 Hadoop、Spark 的监控,监控指标有近千个,可以满足对大数据平台的监控需求。
和前面提到的 Nagios 一样,Ganglia 的 gmetad 收集的时间序列数据通过 RRD 存储,RRDTool 作为绘图引擎使用并生成相应的图形显示,以 Web 方式直观地提供给客户端。Ganglia 也拥有灵活的数据标准和插件生态,可以很方便地在默认监控指标上引用或者定制其他扩展指标。这一特性在大数据领域也获得了认可,Hadoop、Spark 等都开放了面向 Ganglia 的指标集,在 GitHub 上也有很多现成的扩展插件。
3.4 Open-Falcon
Falcon 是猎鹰、隼的意思,鹰眼具有精准、洞穿的特点。Open-Falcon 是小米开源的监控系统,是为了解决 Zabbix 的不足而出现的产物,它由 Go 语言开发而成,小米、滴滴、美团等超过 200 家公司都在不同程度上使用 Open-Falcon。小米同样经历过 Zabbix 的时代,但是当机器数量、业务量上来以后(尤其是达到上万上报节点),Zabbix 在性能、管理成本、易用性、监控统一等方面就有些力不从心了。Open-Falcon 具有数据采集免配置、容量水平扩展、告警策略自动发现、告警设置人性化、历史数据高效查询、Dashboard 人性化、架构设计高可用等特点。Open-Falcon 的文档目前分为 0.1 和 0.2 版本,且每个版本都有中、英两个版本,社区贡献了 MySQL、Redis、Windows、交换机、LVS、MongoDB、Memcache、Docker、Mesos、URL 监控等多种插件支持,其架构如图 1-13 所示。
如图 1-13 所示,使用 Open-Falcon 需要在 Linux 服务器上安装 Falcon-agent,这是一款用 Go 语言开发的 Daemon 程序,用于自发现且采集主机上的各种指标数据,主要包括 CPU、磁盘、I/O、Load、内存、网络、端口存活、进程存活、ntp offset(插件)、某个进程资源消耗(插件)、netstat 和 ss 等相关统计项,以及机器内核配置参数等指标,指标数据采集完成后主动上报。Falcon-agent 配备了一个 proxy-gateway,用户可以使用 HTTP 接口将数据推送到本机的 Gateway,从而将数据转发到服务端。Transfer 模块接收到 Falcon-agent 的数据以后,对数据进行过滤梳理以后通过一致性 Hash 算法发送到 Judge 告警判定模块和 Graph 数据存储归档模块。Heartbeat server(心跳服务)简称 HBS,每个 Agent 都会周期性地通过 RPC 方式将自己的状态上报给 HBS,主要包括主机名、主机 IP、Agent 版本和插件版本,Agent 还会从 HBS 获取需要执行的采集任务和自定义插件。
Open-Falcon 具有如下特性:
强大灵活的数据采集能力:自动发现,支持 Falcon-agent、SNMP、用户主动推送、用户自定义插件、OpenTSDB 类型的数据模型(timestamp、endpoint、Metric、key-value tags)。
水平扩展能力:支持每个周期上亿次的数据采集、告警判定、历史数据存储和查询。
高效率的告警策略管理:支持高效的 portal、策略模板、模板继承和覆盖、多种告警方式、callback 调用。
人性化的告警设置:最大告警次数、告警级别、告警恢复通知、告警暂停、不同时段不同阈值、维护周期。
高效率的 Graph 组件:单机支撑 200 万指标的上报、归档、存储(周期为 1 分钟)。
高效的历史数据 query 组件:采用 RRDTool 的数据归档策略,秒级返回关于上百个指标一年的历史数据。
Dashboard:多维度的数据展示,用户可自定义 Screen。
高可用:整个系统无核心单点,易运维,易部署,可水平扩展。
开发语言:整个系统的后端全部用 Golang 编写,portal 和 Dashboard 则用 Python 编写。
3.5 ZMon
如果公司规模较小,不需要 Prometheus 这种级别的监控系统,那么可以考虑使用荷兰电商 Zalanado 公司开源的 ZMon 这款天然的分布式监控及告警系统。ZMon 和 Prometheus 一样,都采用拉模式,但需要在监控的目标上安装 Check 来抓取指标信息,这些 Check 都分布在一个个 Python 编写的 Worker 上,其可对目标和站点进行 Check 操作(类似于 Prometheus 中的 Exporter 的概念)。Worker 采集到的数据在 ZMon 中采用 KairosDB 进行存储,KairosDB 底层使用的是 Cassandra 进行存储。KairosDB 支持 Grafana 集成、一般的计算函数、Tag 级指标支持、Roll-up 预聚合,适用于中大规模 DevOps 团队自治的场景。从左到右看图 1-14 所示的架构,ZMon 更像是一个任务队列分发的分布式系统,图左侧的用户端生成一些 Check 和 Alert 的任务,通过队列分发给图右侧后端可以无限扩展的 Worker,这些 Worker 执行程序检查目标,将告警和数据传递给用户端和存储层 KairosDB。
ZMon 具有如下特性:
支持自定义 Check 和 Alert,团队之间可以共享 Check,通过继承重用 Alert 并定制告警级别。
支持 Dashboard 和 Grafana。可以根据团队和 Tags 定义带有小部件和告警过滤器的自定义仪表盘。由于是 KairosDB 存储,可以直接使用 Grafana 从 KairosDB 数据源中绘制数据仪表盘。
支持 Python 表达式。Check 和 Alert 都是任意的 Python 表达式,提供了很大的灵活性和强大的功能。Python 可以在平台部署中将很多底层任务和系统完美集成。
支持推送通知:支持推送技术订阅来实现自告警,可以向电脑桌面和手机发送提醒。
支持 Rest API 监控。收集应用程序的 API 指标之后,ZMon 的云 UI 可以帮助用户直观地了解服务中正在发生的事情,可以呈现出不同的 API 路径以及相关指标。
支持对每个实体的告警进行概述。ZMon 可以提供告警的全局视野以及每个实体的具体信息,每个实体也可以通过搜索的形式,显示映射到这些实体的所有告警及其当前状态。
支持试运行和即时评估。比如可以在 UI 页面始终执行 Check 和 Alert,以试运行的形式快速获取反馈结果。
4 监控系统的选型分析及误区探讨
衡量一款监控系统是否符合需求,需要从多个维度进行考察。本节我们就从功能、性能、数据存储、服务发现、运维管理、开发语言、社区力度及生态发展、误区探讨这 8 个角度进行监控系统的选型分析。
4.1 功能
首先就是功能维度,它直接决定了能否实现开箱即用,从而缩短项目周期、降低成本等。如果一款监控系统达不到想要的功能,那么就需要进行二次开发,这样会增加项目的技术难度、复杂度以及延长项目周期等。
表 1-3 从主要维度对主流监控系统做了评估。
比如在功能上,相对于 Open-Falcon,为什么会出现滴滴内部的基于 Open-Falcon 的 DD-Falcon?是因为在功能上 DD-Falcon 相比于 Open-Falcon,主要进行了如下改进。
监控数据按服务单元分类。
增加垃圾数据清洗。
分级索引。
精简 RRA。
巡检大盘支持同环比。
重组看图首页。
报警数据获取由推模式变为拉模式。
去除告警模板。
重新定义 nodata。
4.2 性能
功能维度是监控系统选型中的一个重要参考维度,但不是唯一的维度。有时候性能比功能还要重要,况且性能和功能很多时候是相悖的,鱼和熊掌不可兼得。
小米初期是使用 Zabbix 来做监控的。Zabbix 大名鼎鼎,成熟稳健,很多公司都在使用。小米也不例外,初期做运维开发的人员比较少,机器量、业务量也少,Zabbix 可以很好地满足需求。但是随着业务的发展,MySQL 出现了性能瓶颈。由于 Zabbix 是使用 MySQL 来存放监控历史数据的,假设一台机器有 100 个监控项,2000 台机器就有 20 万个监控项。监控系统的数据采集没有高峰低谷,是持续性的、周期性的,一般是 1 分钟采集一次。机器量越来越大,数据量就越来越大,MySQL 的写入逐渐成为瓶颈。小米尝试使用了业界的一些 Proxy 的方案,也尝试把采集周期调长,比如 3 分钟采集一次或者 5 分钟采集一次,但是都治标不治本。Zabbix 有些数据采集是通过拉的方式,也就是服务器端主动探测的方式,当目标机器量大了之后,拉任务也经常出现积压。这些问题直接导致维护 Zabbix 的技术人员焦头烂额。因此,Falcon 横空出世,Falcon 经过了数家公司 2 亿多指标的海量数据验证,在稳定性、易用性方面都没有问题。
Prometheus 也支持大规模的集群部署,在 2019 年结束的阿里“双十一”活动中,阿里云中间件官方在《不一样的双 11 技术:阿里巴巴经济体云原生实践》电子书中宣布 Prometheus 在全球大促中经受住了洗礼。连阿里内部的鹰眼系统也发布了全托管版的 Prometheus 服务,解决了开源版本部署资源占用过大、监控节点数过多时的写入性能问题,对于大范围、多维度查询时查询速度过慢的问题也做了优化。优化后的 Prometheus 托管集群在阿里内部全面支持 Service Mesh 监控以及几个重量级的阿里云客户,许多优化点也反哺了社区。托管版的 Prometheus 兼容开源版本,在阿里云的容器服务上可以做到一键迁移到托管版。
如图 1-15 所示,面对海量的监控数据和性能压力,阿里使用了联邦(Federation)的架构将监控压力分担到多个层次的 Prometheus 并实现全局聚合。在联邦集群中,每个数据中心部署单独的 Prometheus,用于采集当前数据中心监控数据,并由一个中心的 Prometheus 负责聚合多个数据中心的监控数据。
针对每个集群的 OS 指标(如节点资源 CPU、内存、磁盘等水位以及网络吞吐)、元集群以及用户集群 K8S master 指标(如 kube-apiserver、kube-controller-manager、kube-scheduler 等)、K8S 组件(如 kubernetes-state-metrics、cadvisor)、etcd 指标(如 etcd 写磁盘时间、DB size、Peer 之间吞吐量)等,架构被分层为监控体系、告警体系和展示体系 3 部分。监控体系按照从元集群监控向中心监控汇聚的角度,呈现为树形结构,其可以细分为 3 层:
边缘 Prometheus:为了有效监控元集群 K8S 和用户集群 K8S 的指标,避免网络配置的复杂性,将 Prometheus 下沉到每个元集群内。
级联 Prometheus:级联 Prometheus 的作用在于汇聚多个区域的监控数据。级联 Prometheus 存在于每个大区域,例如中国区,欧洲美洲区、亚洲区。每个大区域内包含若干个具体的区域,例如北京、上海、东京等。随着每个大区域内集群规模的增长,大区域可以拆分成多个新的大区域,并始终维持每个大区域内有一个级联 Prometheus,通过这种策略可以实现灵活的架构扩展和演进。
中心 Prometheus:中心 Prometheus 用于连接所有的级联 Prometheus,实现最终的数据聚合、全局视图和告警。为提高可靠性,中心 Prometheus 使用双活架构,也就是在不同可用区布置两个 Prometheus 中心节点,都连接相同的下一级 Prometheus。
通过这样的架构部署模式,阿里的 Prometheus 从容应对了 2019 年“双十一”巨大流量带来的性能挑战。因此,性能是根据当前业务量做技术评估的一个重要因素。
4.3 数据存储
Zabbix 采用关系数据库保存,这极大限制了 Zabbix 采集的性能。Nagios 和 Open-Falcon 都采用 RDD 数据存储,Open-Falcon 还加入了一致性 Hash 算法分片数据,并且可以对接到 OpenTSDB,而 Prometheus 自研了一套高性能的时序数据库,在 V3 版本可以达到每秒千万级别的数据存储,通过对接第三方时序数据库扩展历史数据的存储。
4.4 服务发现
在当下这个微服务与容器化的时代,很多企业的监控系统中,所有组件及配置均实现了容器化并由 Kubernetes 编排。如果需要在任意 Kubernetes 集群里都实现一键部署,且需要变更系统时仅需修改相关编排文件,那么 Prometheus 就是不二的选择了。Prometheus 的动态发现机制,不仅支持 swarm 原生集群,还支持 Kubernetes 容器集群的监控,它是目前容器监控最好的解决方案。
4.5 运维管理
监控在运维中的核心地位不可动摇。
记得有一个老运维人员说过这么一句话:“监控如果真的做完美了,我们运维也就可以高枕无忧了,每天可以就看看监控数据,然后各种‘挑刺儿’就行了。”一言以蔽之,监控系统需要以人为本,让人使用、管理起来方便。
比如小米在研发 Open-Falcon 之前就面临着如下运维管理问题。
管理成本高昂。为了让 Zabbix 压力小一点,整个公司搭建了多套 Zabbix,比如多看自己用一套、电商自己用一套、米聊自己用一套,如果要做一些公司级别的统计,需要去多个数据源拉取数据。每套 Zabbix 都得有运维人员跟进,人力成本上升。
Zabbix 有易用性问题。比如 Zabbix 的模板是不支持继承的,机器分组也是扁平化的,监控策略不容易复用。Zabbix 要采集哪些数据,是需要在服务器端做手工配置的,而这是一个本该省去的操作。
微服务监控有四大难点,分别是:
配置难。监控对象动态可变,无法进行预先配置。
融合难。监控范围非常繁杂,各类监控难以互相融合。
排查难。微服务实例间的调用关系非常复杂,故障排查会很困难。
建模难。微服务架构仍在快速发展,难以抽象出稳定的通用监控模型。
很多负责监控相关工作的读者在实际工作中会遇到告警的对接、告警的收敛、告警的可用性等问题,这些都是运维管理中需要考虑的问题。而 Prometheus 在这些方面都有解决方案。
2018 年,爱可生数据库平台监控系统在数据库沙龙专场做过一次案例分享,这个案例对运维过程中的告警对接、收敛、可用性做了形象化的展示。
我们是一家乙方公司,通常服务于各种甲方,不同甲方有不同的需求。比如甲方如果有自己的监控系统,就会希望我们的监控系统能与它的监控系统进行对接。在与甲方接触过程中,我们曾遇到过这样的客户。有一天客户跟我们说他最新买的苹果手机被他换掉了,因为他的手机经常会死机,死机的原因就是他收到了太多的告警,最后他专门买了一个安卓手机用来接收告警。所以我们的第二个告警需求是,将告警进行收敛。假如长时间没有收到告警消息,你们是会认为自己的系统运行得很完美,还是会担心告警系统挂掉了?如果是告警系统挂掉了,不能及时把告警发出来,那么最后这个锅到底由谁来背?大家都不希望背锅,所以第三个告警问题是解决告警的可用性问题。
当然,运维管理还需要考虑到 Web 功能、画图展示、默认监控等。
以 Nagios 和 Zabbix 为例。一般来说,Nagios 更容易上手,但 Zabbix 界面更美观。Zabbix 的画图功能用得更舒服,且 Zabbix 会有很多默认监控,这给运维管理带来非常省心、舒适的感觉,Zabbix 后续的批量监控实施也更为简单。对于 Nagios,如果写好自动化脚本,处理相关工作也很简单,问题在于写自动化脚本很费神。
Prometheus 虽然本身的画图展示功能非常一般,但是它借用了开源的产品 Grafana,结合 Grafana 后,Prometheus 的画图功能实现了质的突破。
4.6 开发语言
从开发语言来看,为了应对高并发和快速迭代的需求,监控系统的开发语言已经从 C 语言、C++语言、Java 语言转移到了 Go 语言阵营,以 Open-Falcon 和 Prometheus 为代表。
Go 语言凭借简单的语法和优雅的并发,在目前云原生场景下使用得越来越广泛。而且,目前在国内市场上,C 语言主要用于单片机等底层开发领域,从中间件开发岗位需求和目前大量 Java 人员转型来看,Go 语言在监控领域的活力还是非常高的。
从全世界来看,我国是 Go 语言爱好者最多的国家。在我国,Go 语言开发者主要集中在北京、深圳、上海 3 个城市。在北京,由于做云计算的公司很多,不论是面向市场的公有云还是自建自用的私有云,开放平台技术、容器技术、集群管理技术、微服务和 Serverless 技术等都是 Go 语言擅长的方向。Go 语言的应用主
要集中在如下方向。
服务器编程。以前使用 C 或者 C++做的那些事情,现在用 Go 来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
脚本编程。完全可以把 Go 当作 Python 来用,日常的各种自动化任务、小工具等都非常适合使用 Go 编写。
网络编程。这一块目前应用最广,包括 Web 应用、API 应用、下载应用。
云平台。目前国外很多云平台都采用 Go 开发,CloudFoundy 的部分组件、前 VMware 的技术总监自己出来做的 Apcera 云平台以及大名鼎鼎的 Docker 都是用 Go 开发的。
如表 1-4 所示,Go 语言的项目中绝大多数可以在 GitHub 上搜到,在那里可以了解每个项目的实际功能、架构和使用场景,由于本书的主题和篇幅问题,这里不再展开。
4.7 社区力度及生态发展
对于目前流行的编程语言,如 Java、Python,如果在使用过程中遇到了一些异常,基本上可以借助搜索引擎来解决,因为一个产品用的人越多,暴露的坑也就越多,对应的解决方案也就越多。这种方法对于监控系统同样适用,这可以让你“站在巨人的肩膀上”解决遇到的问题。
Zabbix、Nagios、Ganglia 的确都是老牌的监控系统,它们分别在 1997、1998、2001 年左右出现,都具有系统稳定、成熟度较高等特点。Open-Falcon 和 Prometheus 都是最近几年才出现的,虽然功能还在不断迭代和更新,但是它们借鉴了很多老牌监控系统的经验。尤其是 Prometheus,作为 CNCF 第二个毕业的作品,其 Google 搜索量和 GitHub 活跃度非常高。Prometheus 也是直接对接 K8S 环境的,非常适合云上使用。
4.8 误区探讨
伴随着企业的发展,企业内部的监控往往会经历无监控、半自动脚本监控、自动化监控、集群式监控、全方位立体监控等阶段。未来的监控,会朝着链路化、全息化、立体化、低成本、自愈性、无人值守等方向发展。
在进行监控系统选型之前可以先问自己一个问题:是否真的需要一个监控?
在搞清楚这个问题之后,还可以继续问自己一个问题:是否需要自己维护一套监控?很多初创型公司为了节省成本会选择直接购买与监控有关的云服务,自己只需要关注如何使用即可,其余的都可以外包出去。也有些公司采用内监控和外监控结合的形式,内监控是企业自己搭建自用监控系统,外监控是用外来的商业监控产品对产品的最外层接口和用户行为进行宏观监控。
很多人面对监控系统时会有一种自研的冲动,自研会有交接问题、KPI 问题。如果之前自研的人不对监控系统进行维护了,会有什么问题?这些自研系统的交接会不会给新人挖坑般的噩梦体验?是否真的有自研的必要?如果不是 KPI 的压迫可以考虑如下问题:目前市面上的监控系统是否真的都无法满足目前业务需求?团队的核心竞争力真的就是监控系统吗?是否有足够的能力、人力、财力、精力来支持自研?
监控选型时切忌一味地追求性能或者功能,性能可以优化,功能可以二次开发。如果要在功能和性能方面做一个抉择的话,那么首选性能,因为总体上来说,性能优化的空间没有功能扩展的空间大。然而对于长期发展而言,生态又比性能以及功能都重要。
监控系统选型还有一个标准,就是尽量贴合团队的自身技术体系栈,比如我们团队是中间件方向、云原生方向,那么 Java 和 Go 语言就是团队自身的技术体系栈。在这个语言的基础上,团队可以合作、奋斗,拿出更多、更好、更棒的成果。
企业处在不同的成长时期也可以选择不一样的监控系统,CMDB+Zabbix 在一定的量级以内还是非常靠谱和稳定的,一台机器就可以完成很多的监控业务。如果业务和技术并没有达到那个量级且中长期达不到那个量级,投入大量人力和物力实现的“巨无霸”,真的非常有意义和价值吗?很多经验丰富的技术人员用过的监控系统应该不下 10 种,每种监控工具都有自己的优缺点,并不是越新的技术就越好,不能盲目跟风,没有最好的,只有最合适的。Nagios 虽然历史悠久,但是在实际运维中依然有它独立存在的意义,在一些基本的监控项目中甚至比高大上的 Prometheus 更加方便。比如针对最基本的监控 ping 和 telnet port,Prometheus 有一个 up 函数,但是其只有两个状态 up 和 down,而 Nagios 对这种状态比较少的监控更为简单直接。盲目追新并不是监控选型的态度,专业的监控架构是综合实际使用情况去做设计、做规划的,可以根据实际情况结合使用多种监控。
十万的用户对应十万的架构方案,百万的用户对应百万的架构方案,千万的用户对应千万的架构方案,亿级的用户对应亿级的架构方案。这就好比我们团队中的一个成员在开会时提出的:“现在我维护的网关系统界面不太好看,我想请前端人员帮我美化一下。”我直接回复:“现在应该没有人接入你的网关吧?当前第一要务是接入,美化的事情并没有接入重要,当前也没有必要浪费前端资源。”什么阶段就应该做什么阶段的事情。
最后要说的就是不要迷信权威,不能人云亦云。不是别人说好就是好,一定要自己亲身试验过才有发言权,实践出真知,大家可以参见我在个人微信公众号“工匠人生”上发布的 Prometheus 作者的文章《PromCon 上 VictoriaMetrics 和 Prometheus 的权威性能和正确性评估》的译文。
《Prometheus云原生监控:运维与开发实战》
推荐语:本书被誉为Prometheus“百科全书”,可以指导读者快速搭建一个Prometheus监控系统并将其应用到实际工作中,囊括私有云、公有云、混合云环境下的大量案例。针对运维人员,分享Prometheus对接各种云原生应用并实现事前预警、事中报警、事后提供翔实数据的方法,针对开发人员,给出了Prometheus主要组件的源码分析以及部分功能的二次开发实现。从入门知识到高级技巧,全面解读PromQL,并给出上百个PromQL实际案例。以附录的形式给出端口、数据类型、选择器、指标类型、PromQL内置函数等实际工作中需要时常查阅的内容。
版权声明: 本文为 InfoQ 作者【华章IT】的原创文章。
原文链接:【http://xie.infoq.cn/article/e1d2ad0d57d9fc6b2bb8fd6a5】。文章转载请联系作者。
评论