【升职加薪秘籍】我在服务监控方面的实践 (1)- 监控蓝图
大家好,我是蓝胖子,关于性能分析的视频和文章我也大大小小出了有一二十篇了,算是已经有了一个系列,之前的代码已经上传到 github.com/HobbyBear/performance-analyze,接下来这段时间我将在之前内容的基础上,结合自己在公司生产上构建监控系统的经验,详细的展示如何对线上服务进行监控,内容涉及到的指标设计,软件配置,监控方案等等你都可以拿来直接复刻到你的项目里,这是一套非常适合中小企业的监控体系。
温馨提示: 本系列主要是搞懂监控什么,如何监控的问题,对于 prometheus 和 grafana 的基本使用和指标类型不会过多的讲解。
如果对 prometheus 的 histogram 直方图和描点原理有疑惑的同学还可以看看我之前的两篇文章,# 【prometheus】分位数统计Histogram原理 和# prometheus描点原理。
完整代码我已经上传到了 github
此篇是监控实践的开篇,我将会介绍我们监控的目的,做什么事情,特别是开发一定要搞清楚做事的目的,之后我会介绍监控的对象,以及监控的方案选型,当然,这篇仅仅是树立起后续我们构建监控系统的蓝图,实际的详细步骤还是会放到后续章节里。现在,让我们开始吧。
监控架构一览
这套监控系统目前还未支持对容器化的服务端架构提供监控,不过你依然能从这套教程里学会常见的监控套路,设计方案。对容器化的服务进行仅仅是监控组件的配置发生变化而已。
如上图所示,是这个系列的监控架构图,主机上运行的应用程序会将各项指标通过接口暴露出来,node exporter 会将机器以及操作系统的指标信息也通过接口暴露出来,prometheus 通过这些接口进行指标采集,采集到的指标将会通过 grafana 建立各种监控面板对其进行显示。
在各个主机上也会有 filebeat 将日志经由 logstash 采集到 elasticsearch 里,elasticsearch 里的日志通过 kibana 进行显示。
在报警方面,我们是自研了一个报警系统,目的是为了针对不同项目组,不同应用服务能有不同的报警策略,目前会将日志等级为 error 的日志报警到对应的项目组钉钉群,同时在 grafana 上也针对监控面板设置告警规则,grafana 触发报警时,同样会回调到这个报警系统。所有应用的报警通知最终都会由报警系统进行发出。
在设计系统时,也需要考虑后续扩容的问题,这套架构主要考虑两个方面的扩容,一个 prometheus 的扩容,一个是 elasticsearch 的扩容。
首先说下 prometheus 扩容的问题,如果后续指标越来越多,单个 prometheus 肯定是不能满足查询和存储要求的,一个可行的方案是用不同的 prometheus 采集不同的业务系统指标。
因为伴随着指标越来越多,我相信也不可能单个团队或者部门需要去浏览所有的服务指标信息,好的方案应该是每个部门或者开发只看他自己需要关注的指标,比如一个大型电商系统,会有许多不同的业务系统,比如营销系统,物流系统,营销系统的开发人员一般是不需要关注物流系统的情况的。每个业务系统开发只需各自安排人员负责各自的业务指标监控即可。所以完全可以不同业务系统使用不同的 prometheus 进行采集。
注意,虽然是对不同业务系统用不同的 prometheus 采集,但是它们的监控面板其实还是一样的,只是指标的数据源不同,通过 grafana 可以用同一套监控面板实现不同数据源的切换。
再来谈谈 elasticsearch 扩容问题,当前的日志采集还是将多个产品线的日志统一收集到一个 elasticsearch 集群里,所以当后续日志量达到一个集群里不能满足查询需求时,首先考虑通过产品线对日志存储进行拆分,不同产品线可以采用不同的集群进行存储。 但是这样没办法解决一个产品线日志量过大的问题。因为我们看日志肯定是多个关联的服务一起看,同一个产品的服务日志肯定不能进程拆分了,那就只有一个方法加 elasticsearch 节点 ,具体加多少节点这也和日志量有关,设置日志定期删除可以缓解日志查询压力。
监控的目的
看完了整个监控报警架构,接着我们看看搞监控的目的是啥?搞清楚这个问题对我们以后如何设计指标十分具有指导意义。
监控最主要的目的是为了及时发现程序问题,这些问题提现在监控指标上可能是短时间内错误次数增多,服务连接数一直在上涨,内存使用量一直增大等,但能发现问题仅仅是第一步,发现问题后还要能定位问题出现的原因 ,往往初学者会犯的一个错误就是监控指标多且杂,但是却不能很好的定位问题出现的原因。
我们往后的指标设计都将围绕着这两个目的去建立我们的相关指标与日志记录,你可以发现,我们做的一切都是建立在发现问题和定位问题这两个目的之上的。
其次,监控也会提供后续容量规划的依据,我们能够通过监控图表很清晰的看出业务高低峰期的流量,压力情况,这些指标对后续业务扩张时的资源评估具有指导意义。
监控的手段
了解了监控的目的,我们还需要知道,我们能通过哪些手段或者说工具来帮助我们监控服务。
常用的监控手段有指标 metric,日志,链路追踪,在我们这个系列里,我么会创建指标以及日志打点的方式对系统服务进行监控,为什么没有用上链路追踪呢?考虑到公司应用目前并没有过多的服务依赖,请求链路不长,硬生生的用上有种杀鸡用牛刀的感觉,就舍弃了,在少量的服务依赖的地方,仅仅用日志打点来代替。
在日志收集方面,我采用了 elasticsearch,kibana,filebeat,logstash 的 elfk 架构构建了一个日志收集查询的平台,在指标方面,采用了 prometheus+grafana 的方案,这也是目前相当成熟的监控选型,资料很多,可以避免踩坑。
如何发现问题
接着,我们来思考下如何设计指标来发现系统服务的问题?简而言之,需要建立哪些指标说明服务是好的或是坏的。
在这方面,谷歌提出了四大黄金指标,它有助于我们衡量服务的质量。四大黄金指标分别是:
1, 延迟 : 也就是请求耗时。 这个值越高,说明服务对外提供服务越慢。
2,流量 : 这类型指标不是单纯的指网络带宽,每秒经过系统的请求数 qps 也可以看成是流量的一种表现,一般情况下,qps 越高,带宽越高,流量型指标能够衡量服务容量。
3,错误数 : 发生错误请求的次数,这类型指标简单粗暴,最能反应服务监控状态,短时间内大量报错肯定是不正常的。
4,饱和度 : 这类型指标能够反映系统的极限能力,比如一个 4 核的 cpu,服务已经要跑满 3.8 核了,那么说明 cpu 要饱和了,反映到应用服务则可能是程序运行缓慢。
四大黄金指标给我们后续创建指标提供了几个维度,我们后续创建指标时也是按这几个维度去创建相应的指标。
业务报警
上述的指标对衡量服务的质量有很好的帮助,但有时我们出现的问题不仅仅是性能上的问题,还可能和业务挂钩,比如业务逻辑得到的结果是错的,如何发现这类问题。
这类型报警设计比较灵活,跟具体需求相关,在我从事的项目里,我往往是添加了结果检查机制,从结果看业务是否正常,比如客户发起了一笔订单,如果发现最后客户扣款了,但是订单对应的商品却没有到手,这种情况则是需要报警的,我们需要建立起这种报警机制,比如定时循环 查询过去 1 小时的付完款的订单,然后看这批订单中是不是存在商品没有收到的情况。如果有,马上将对应的客户订单号进行报警,进行排查。
这类型的报警可能会涉及到写检查机制的代码,或者定时 sql,所以一般只针对很核心的业务就行。
报警方式的选择也很灵活,钉钉邮件皆可。
如何定位问题
知道了如何创建指标了,我们后续就可以通过相应的指标创建报警规则,从而能够发现问题,但是根据这些指标能不能定位到问题呢?这将是我们时时刻刻需要想的。
我们知道一个应用服务是有组件依赖的,首先服务运行于操作系统上,所以应用服务想要健康,操作系统也必须是正常才行,同时应用服务依赖很多中间件,mysql,redis,消息队列等等,这些组件也都必须正常才能保证应用服务是正常的。
所以你可以看到如果你应用服务的某个指标异常了,你可能会去中间件或者操作系统层面去看它们的指标是否正常。整个监控其实是分层的。
分层监控是我们在建立指标时需要考虑的,通过分层监控,能够定位到发生问题的根本原因是在哪一个层次。
我们通常按照机器监控,中间件监控,应用监控,业务监控这几个层次去进行监控指标的设计,多个层次间的指标往往是相互影响的。比如当你发现在应用监控层的服务 qps 的指标变大了,由于应用可能会请求 redis,mysql 等,所以在中间件这一层的某些流量类型指标也会变大。
最好能定位到具体代码
仅仅分层监控去设计指标还不足以定位到问题的根本原因,因为我们出问题常常是代码的 bug 导致,比如 定位到了是 mysql 的问题, 你发现 mysql 的更新请求突然增加了,导致 mysql 的 cpu 和内存上涨,但是你能通过它去发现这是哪段程序导致的吗?显然不能。
我们需要更细致的指标,和业务挂钩的指标,数据库和业务挂钩的就是 sql 和表,如果我们没有开审计日志的话,也可以设计按表维度去记录每个表的 crud 操作次数,这样能快速定位到是哪张表引起的更新,通过表名大致定位问题代码。
类似的在对 redis 建立指标时,可以按业务功能去划分各个业务功能操作的次数,不过这要求我们在对 redis key 命名的时候要严格遵守相关开发规范,通过前缀名去划分不同的业务。
除此以外,应用服务出现 cpu,内存上涨时,也要求定位到问题代码,这种机制可以采用与开发语言相关的一些监控工具,对于 golang 而言,有自带的 pprof 工具,像 java,有 jconsle 等等。我们可以在服务 cpu 或其他指标异常时,迅速进行采样,在后面我也会用 golang 服务具体演示这一步要如何做。
请记住,你监控设计时做的一切不仅要发现问题,还要想想在发现问题后,如何快速定位问题。
总结
简单总结下,这一节我们主要了解了整个系统的监控架构,以及监控的目的,如何去设计指标,让自己对监控 相关的知识有个谱。 在接下来的时间,我们就要正式动手开干了。
在万千人海中,相遇就是缘分,为了这份缘分,给作者点个赞👍🏻不过分吧。
版权声明: 本文为 InfoQ 作者【蓝胖子的编程梦】的原创文章。
原文链接:【http://xie.infoq.cn/article/c91c8910bb0d44177f76d6587】。文章转载请联系作者。
评论