Prometheus是SoundCloud公司开源的监控系统,同时也是继Kubernetes之后,第二个加入CNCF的项目。Prometheus是一个优秀的监控系统,沃趣围绕着Prometheus先后开发了多个组件,包括基础告警组件,服务发现组件、各种采集的Exporters等,这些组件结合Prometheus支撑了沃趣大部分的监控业务。本文主要介绍Prometheus,从他的来源,架构以及一个具体的例子等方面来说明,以及沃趣围绕Prometheus做了哪些工作。
起源
SoundCloud公司的之前的应用架构是巨石架构,也就是所有的功能放在一个大的模块里,各个功能之间没有明显的界线。巨石架构的应用主要存在两方面的问题,一方面在于很难对其进行水平扩展,只能垂直扩展,但是单台机器的能力毕竟是有限的;另外一方面在于各个功能耦合在一块,新增一个功能需要在已有的技术栈上进行开发,并且要确保不会对已有的功能造成影响。于是他们转向了微服务架构,将原有的功能拆分成了几百个独立的服务,整个系统运行上千个实例。迁移到微服务架构给监控带来一定的挑战,现在不仅需要知道某个组件的运行的情况,还要知道服务的整体运行情况。他们当时的监控方案是:StatsD + Graphite + Nagios,StatsD结合Graphite构建监控图表,各个服务将样本数据推送给StatsD,StatsD将推送来的样本数据聚合在一起,定时地推送给Graphite,Graphite将样本数据保存在时序数据库中,用户根据Graphite提供的API,结合自身监控的需求,构建监控图表,通过图表分析服务的指标(例如,延迟,每秒的请求数,每秒的错误数等)。
![e6b64669d2fe93207882e5a62ba0d0fc.png](https://i-blog.csdnimg.cn/blog_migrate/f2f1b88a1dc2dd1d0d08fc054546872b.jpeg)
那么这样一种方案能满足微服务架构对监控的要求么?什么要求呢:既能知道服务整体的运行情况,也能够保持足够的粒度,知道某个组件的运行情况。答案是很难,为什么呢?例如,我们要统计api-server服务响应POST /tracks请求错误的数量,指标的名称为api-server.tracks.post.500,这个指标可以通过http状态码来测量,服务响应的状态码为500就是错误的。Graphite指标名称的结构是一种层次结构,api-server指定服务的名称,tracks指定服务的handler,post指定请求的方法,500指定请求响应的状态码,api-server服务实例将该指标推送给StatsD,StatsD聚合各个实例推送来的指标,然后定时推送给Graphite。查询api-server.tracks.post.500指标,我们能获得服务错误的响应数,但是,如果我们的api-server服务跑了多个实例,想知道某个实例错误的响应数,该怎么查询呢?问题出在使用这样一种架构,往往会将各个服务实例发送来的指标聚合到一块,聚合到一起之后,实例维度的信息就丢失掉了,也就无法统计某个具体实例的指标信息。
![2e205baf723a510160e559c304f0411e.png](https://i-blog.csdnimg.cn/blog_migrate/c52671a611b13af3f6e378c57b389ff9.jpeg)
StatsD与Graphite的组合用来构建监控图表,告警是另外一个系统-Nagios-来做的,这个系统运行检测脚本,判断主机或服务运行的是否正常,如果不正常,发送告警。Nagios最大的问题在于告警是面向主机的,每个告警的检查项都是围绕着主机的,在分布式系统的环境底下,主机down掉是正常的场景,服务本身的设计也是可以容忍节点down掉的,但是,这种场景下Nagios依然会触发告警。
![20b0e2b6a7675e8739097b56223662e5.png](https://i-blog.csdnimg.cn/blog_migrate/db59d38cf027e75a6f95969ccce5db52.jpeg)
对比Prometheus,你会发现这两个系统非常相似。实际上,Prometheus深受Borgmon系统的影响,并且当时参与构建Google监控系统的员工加入了SoundCloud公司。总之,种种因素的结合,促使了Prometheus系统的诞生。
Prometheus的解决方案
那么,Prometheus是如何解决上面这些问题的?之前的方案中,告警与图表的构建依赖于两个不同的系统,Prometheus采取了一种新的模型,将采集时序数据作为整个系统的核心,无论是告警还是构建监控图表,都是通过操纵时序数据来实现的。Prometheus通过指标的名称以及label(key/value)的组合来识别时序数据,每个label代表一个维度,可以增加或者减少label来控制所选择的时序数据,前面提到,微服务架构底下对监控的要求:既能知道服务整体的运行情况,也能够保持足够的粒度,知道某个组件的运行情况。借助于这种多维度的数据模型可以很轻松的实现这个目标,还是拿之前那个统计http错误响应的例子来说明,我们这里假设api_s