Prometheus Grafana集成的监控系统已经是云原生的绝配,但是Prometheus指标到底该如何使用?Grafana到底该如何展示仍然值得思考和推敲。
先说下思考,监控和告警看的是现象而不是原因,通过现象进行具体问题分析。除非某个原因(某个服务导致的时延)是确定的,那么既然问题是确定的,为什么不能直接解决呢? 但这就是现实中的平常想象,只能通过监控和告警来查看已知的问题。
监控设计不能太复杂,监控可以用来衡量服务的健康程度,那么监控自身的稳定性如何保证呢?学会做减法,删除没必要的监控和告警。
1、首先说说Prometheus指标,分类有四种
- Gauges:仪表盘类型,可增可减,如CPU使用率,内存使用率,集群节点个数,大部分监控数据都是这种类型的
- Counters:计数器类型,只增不减,如机器的启动时间,HTTP访问量等。机器重启不会置零,在使用这种指标类型时,通常会结合rate()方法获取该指标在某个时间段的变化率
- Histograms:直方图,用于观察结果采样,分组及统计,如:请求持续时间,响应大小。其主要用于表示一段时间内对数据的采样,并能够对其指定区间及总数进行统计。
- Summary:类似Histogram,用于表示一段时间内数据采样结果,其直接存储quantile数据,而不是根据统计区间计算出来的。不需要计算,直接存储结果。
其中仪表盘和计数器使用比较简单,展示的是一个数字和一段时间内的趋势。比如可以使用计数器统计一段时间内的缓存命中次数或者某个应用的调用次数,其使用也非常简单,只需要按照某个维度进行递增,Prometheus存储时会关联时间戳,这样你就可以查询出某个维度在某个时间段内的走势或者数量。
比较令人费解的是Histograms和Summary,Summary表示一段时间内的采样结果,并且直接存储相应区间比例的结果,比如一段时间内的响应时间准确数值,所以这种数值是什么就是什么,不能进行再次聚合计算。
Histograms是一个对采样点进行统计的指标,并不一定是某个时间段内的指标,而是把相应的指标放到一个桶里,然后返回给客户端,由客户端进行聚合计算。在分桶合理的基础上就可以在Grafana客户端动态计算指标的占比,比如统计一些长尾数据比例。
2、说完了指标的含义,那么这些指标如何收集呢?
我这里一般把收集分为两种(这里说的指标收集,也就是说的编写Exporter)
- 跟业务强耦合的收集,比如需要统计业务逻辑内部指标,比如内部函数调用时延,某个关键词出现次数,异常次数、频率;并且这种数据不太容易通过网络协议传递出去的指标。如果需要收集这种指标数据,那就把Prometheus官方提供的相应sdk集成到代码中,在代码中注册并调用相应指标类型API即可。
- 跟业务弱耦合的收集,比如需要收集Http接口调用的次数和延迟,这种一般推荐在网路代理端进行收集指标,一来对业务逻辑没有侵染,二来每个服务都可以共享这个收集服务,维护成本更低。即便没有网络代理,也可以统一拦截。比如Java项目就可以通过一个jar包实现spring的过滤器或者拦截器接口,然后在服务启动的时候以agent的形式加载进去即可。
3、那么具体该收集什么指标呢?
QPS、资源占用、延迟、错误率,基本就这四类指标,但千人千面,不同的业务,不同的对象,需要的指标都是不一样的,这里有一个原则,需要了再加,加上了一定能够体现其价值和作用,宁缺毋滥。
就像做一个服务一样,第一个版本一般都比较简单,随着迭代会慢慢加上一些指标,时间久了,可能还需要删除掉或者改进一部分指标。
这里有一个简单的小窍门,当你排查某个问题的过程,百思不得其解,最后发现了问题的根因,可以把这个根因添加到监控指标中,比如某个服务的时延导致的异常、某个bug导致的逻辑错误...那么当你在监控面板中发现类似错误指标出现时,能给你带来解决问题的思路和方向,这就是指标本身的意义,能够显著提高工作效率,减少人肉的过程。
数据采集相对比较简单,Prometheus提供了pull和push两种模式,一般情况下都是指标存在本地,等待Prometheus pull数据。
4、数据指标都有了Grafana如何展示呢?
很多人喜欢Grafana的炫酷,但这种人一般都是老板,真正的程序员还是喜欢Grafana的简单和实用,另外Grafana自身就是展示Prometheus采集的指标。
对于一个团队或者公司而言,一般分为两种面板。一是整体服务的面板,这种可以看到所有服务的整体情况,面向于不清楚服务细节的人群;二是详细面板,这种面板精确到特定服务的真实运行情况,面向的是需要了解服务细节的人群。
Grafana面板简单易用,基本拖拽就可以完成,但是在做的过程中不仅仅是炫酷,更多的是清晰明了,如果说你做了一个面板让一个外行人能够看明白服务的运行情况,基本上就差不多了。这就要求在做的过程中要注意层次和分类、命名有意义。
5、剩下的基本就是告警了
因为我们不可能时刻守在电脑屏幕旁边,这就需要一种机制,当出现问题,能够立马收到通知。告警自身就是使用了监控指标,如果监控指标做的有意义,告警就没有什么问题。告警的智能处置需要比较高的开发和运维成本,没有形成规模之前不用考虑,否则会出现一些似是而非的东西。
发出的告警尽可能分级别,一般错误 消息告警、严重错误 电话告警;告警一定要发给正确的人,并且能够干涉或者处置,否则不必要发出告警。比如每次重新上线或者版本发布发生的重启也会发生告警,然后每次不得不静默告警或者搞得鸡犬不宁,类似这种告警我们就要想办法优化,比如可以使用k8s pod重启变化率,而不是检测到重启就告警。
洋洋洒洒说了一大坨,并不能起到什么卵用,最主要还是结合自身业务场景推敲和思考,形成自己的东西,进而产生真正的业务价值。