Posted on:
Last modified:
“你说说,没有仪表盘的车,你敢开吗?”
按照层级,监控大概分三类:
不要想着把所有的数据都显示到监控上,太多了反倒让人失去重点。想象一下最容易出错的情况, 以及在这种情况下你应该怎么用监控来排错,把这些数据列上去就行了。
系统的每个部分都应该有一个监控,至少让你大概知道这个系统现在的情况如何。
也不要想着把特别复杂的业务数据画到监控系统上,监控是监控,业务是业务,不能相互替代。想要 查询业务数据应该用 BI 系统,而不是监控系统。
监控系统的基础是时序数据库,现代的监控系统一般都有如下几部分组成:
指标收集 + 时序数据库 + 前端显示 + 报警系统
一般需要实现的功能:
从监控的层次划分的话,一般包含三层监控:
现代的监控越来越关注应用层和其他层数据的整合能力,具有快速找到系统瓶颈,方便扩容或代码优化。
监控数据往往都带有时间戳,其实就是一种典型时间序列数据,而这方面已经有很多专门的存储系统, 如 opentsdb,influxdb,prometheus 等。相比 mysql 这样的关系数据库,这类系统在存储、查询上 针对时间序列数据都做了特别的优化。
其中 opentsdb 基于 hadoop 生态系统,考虑到搭建的复杂度,暂时不考虑了。influxdb 和 prometheus 都是 Golang 编写的,直接一个二进制文件就可以运行。两者的区别有:
首先问自己一个问题:当我的程序出了问题的时候,我需要哪些数据来 debug 呢?
Google SRE Book 中提出了四个黄金原则:延迟、流量、错误数、饱和度(需要排队无法提供服务的 时间)。实际使用中对于资源可以使用 USE 指标,对于在线服务可以使用 RED 指标。
被监控服务的类型
就监控而言,服务大概可以分为三类:在线服务,离线处理 和 跑批任务。
此类系统的关键指标在于 QPS, 错误率和延迟。正在进行中的请求的数量也有用。
在线服务系统在客户端和服务端都应该做监控。如果两遍有不同的行为,那么这个对调试是很有意义的。如果一个服务有很多客户端,也不可能让服务监控每个客户端,所以客户端肯定需要依赖自己的数据。
当你按照 query 开始或结束统计数量一定要使用一致的标准。推荐使用结束来作为标准,因为比较容易实现,而且能统计错误和延迟。
对每一个 stage, 记录进入的 item 的数量,有多少在处理中,上次你处理某个东西的时间,多少 item 被发送出去。如果你采用的是批处理,也应该记录进出的批的数量。
更好的方法是通过系统发送一个心跳包:一些带着时间戳的 dummy item 通过整个系统。每个 stage 都输出他看到的最近的时间戳,这样你就知道一个 item 需要多长时间才能经过整个系统了。
关键指标是上次成功操作的时间。
This should generally be at least enough time for 2 full runs of the batch job. For a job that runs every 4 hours and takes an hour, 10 hours would be a reasonable threshold. If you cannot withstand a single run failing, run the job more frequently, as a single failure should not require human intervention.
对于其他的子系统而言,可以选择如下指标
如果一个库会访问进程外的资源,比如网络硬盘等等,至少要记录下所有的访问次数,错误和延迟。
Depending on how heavy the library is, track internal errors and latency within the library itself, and any general statistics you think may be useful.
As a general rule, for every line of logging code you should also have a counter that is incremented. If you find an interesting log message, you want to be able to see how often it has been happening and for how long. 一个比较通用的规则,对于每一条日志,应该有一个计数器。如果你发现了一条有有意思的信息,你肯定想知道这件事
Failures should be handled similarly to logging. Every time there is a failure, a counter should be incremented. Unlike logging, the error may also bubble up to a more general error counter depending on how your code is structured.
对于所有的线程池来说,核心指标是排队的请求的数量,正在使用的线程的数量,总线程的数量, 已经处理的任务的数量和处理任务花费的时间,以及任务排队花费的时间。
缓存核心指标是总的查询数,命中数,总的延迟以及缓存所对应的线上系统的查询数量,错误率,延迟。
监控的核心目标还是护航业务稳定,保障业务的快速迭代,永远不要忘记因何而来。不要为了监控而监控,盲目提高监控或者告警的数量。
© 2016-2022 Yifei Kong. Powered by ynotes
All contents are under the CC-BY-NC-SA license, if not otherwise specified.
Opinions expressed here are solely my own and do not express the views or opinions of my employer.
友情链接: MySQL 教程站