gitbook/高楼的性能工程实战课/docs/361138.md
2022-09-03 22:05:03 +08:00

141 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 09 | 如何设计全局和定向监控策略?
你好,我是高楼。
纵观软件性能行业的发展历程十几年前当性能测试刚刚在国内出现的时候我们只守着工具不管是在培训还是在工作中只要学会了性能测试工具就可以横行市场。那个时候会不会使用LoadRunner就是会不会做性能的标准。
然而性能测试行业发展到现在我们仍然能看到在很多场合中大家还是在讲性能测试理论和思维还是在讲性能测试工具的使用和实现。虽然也有性能监控部分的数据说明但大部分也都只是停留在数据的罗列上描述一下CPU 90%、内存不足、IO 100M之类的现象。
至于为什么会是CPU 90%?如何定位到具体的原因?解决方案又是什么?大部分性能工程师都是不知道的,甚至连思路都说不上来。这就是当下行业的现状了。
前段时间我看到一个微信群里展开了一场讨论。有一个人去面试性能职位被问到“某一天夜里生产上的数据库的CPU突然飙升该怎么去定位问题原因”。群里议论纷纷有人说是因为固定的批量执行计划有人说要看监控数据看慢SQL等等总之就是一群人在猜来猜去。
最后面试官直接给出答案因为Redis被击穿导致数据库压力大所以CPU高。看到这个答案当时就有人觉得这和题目中描述的现象并没有什么直接的逻辑关系。
通过这个事情,我们可以看到,性能监控数据不足带来的问题就是没有分析的证据链。而我一直在强调,从现象到结论要有完整的分析链路,只有这样才是真正的性能分析,否则就是在连蒙带猜做性能。
现在有很多企业(不管是互联网大厂,还是金融机构等)的监控都看似做得挺全面,但其实并没有监控层级的细化。而不做监控的细化,导致的问题就是,经常会出现需要分析某个数据时,只能重新运行场景去抓取数据,并且还要临时添加监控工具。
所以基于上述种种现状,今天这节课我要跟你讲一讲如何设计全局定向监控策略,我希望你能明白从全局到定向的思路,事先设计好监控策略的重要性。
在设计监控策略时,我们第一步是分析架构。通过分析架构,我们要确定有哪些需要监控的点。
## 分析架构
我们先列出这个课程所示例的系统中都有哪些机器。
![](https://static001.geekbang.org/resource/image/64/1e/640da7cdb93cbaac52739ed33c1d641e.png)
在前面的[第4讲](https://time.geekbang.org/column/article/356789)里,我们已经画出了系统架构,如下所示:
![](https://static001.geekbang.org/resource/image/f2/2f/f2294e162a078c7053ef0887f86b762f.png)
从上面的信息中,我们要列出需要监控的组件,也就是下面的这张表格。请你注意,对于上面的各层实例,我们现在只配置了一个,但并不是说我们只需要一个,在后续的测试过程中,当需要增加实例时,我们再增加。
![](https://static001.geekbang.org/resource/image/40/bc/4014b5e22c01d1f499e528ced19898bc.jpg)
## 监控工具选型
基于上面的组件列表,我们接下来要选择相应的监控工具。有一点你要注意,这是我们选择的第一层监控工具,也就是全局监控工具。对于定向监控中需要的工具,我们现在还无法确定,因为定向监控工具取决于性能分析过程中有什么问题。
在我们通过全局监控计数器发现问题之后,想要定位问题的具体原因是什么,就需要分析更详细的监控数据。但是这一点,全局监控计数器无法做到,所以我们需要选择合适的定向监控工具,得到更细的监控数据,我称之为定向监控。
不难理解全局监控和定向监控的区别就是全局监控是第一层的监控它可以将一个技术组件的各个模块的关键性能体现出来比如说操作系统的CPU就是典型的全局监控计数器。
下面我们来看怎么选择全局监控工具。
* **全局监控策略和工具选型**
我们说,全局监控是为了判断整个系统的瓶颈点在什么方向,但并不能给出具体的原因。基于这一点,我们在选择全局监控工具时,要注意几个关键点:
1. **数据精准**:这一点非常重要,因为对于性能计数器来说,数据的精准直接决定了下一步的步骤。
2. **成本低**:这里的成本包括费用和人工成本。不管是成型的收费产品、免费产品、自主研发产品,还是组合产品,费用都是容易计算的,我就不多啰嗦了。对于人工成本,我们直接拿员工的工资和时间计算就行。如果是做临时的项目,我建议最好选择比较流行、通用的监控工具。
3. **范围大**:也就是监控工具要足以覆盖全局监控计数器。在[第4讲](https://time.geekbang.org/column/article/356789)中,我们讲了怎么构建性能分析决策树,而监控工具要做的就是,把性能分析决策树列出的计数器都尽量覆盖全。如果工具能力实在有限,又没时间扩展,那就要在选择好工具之后,明确哪些计数器无法监控到。然后在性能分析的过程中,使用命令弥补工具上的不足。
4. **历史数据可保存**:在性能项目中,实时查看性能数据是必要的,而监控的历史数据可保存也至关重要。因为在场景执行结束后,我们做性能分析和性能报告时会使用到历史数据。
基于这几点,接下来我们就要选出对应的全局监控工具。
根据这个系统的架构我们选择的工具要监控到这几个层面第一层物理主机第二层KVM虚拟机第三层Kubernetes套件第四层各种应用所需要的技术组件。
![](https://static001.geekbang.org/resource/image/ae/de/aeabb079616dc3c9426d2b8e92f739de.jpg)
因此,对应的监控工具如下表所示。
![](https://static001.geekbang.org/resource/image/02/0a/02df644a1c9ae9391141f2a0e03cb40a.jpg)
以上工具都是免费、开源的,可以完全满足我们的监控需求,我们只要部署一下就行。对于其中的操作系统监控工具,我们在[第4讲](https://time.geekbang.org/column/article/356789)RESAR性能分析逻辑中就已经说明了它的局限性你要是忘记了可以再回顾一下。
在我们这个系统中物理机和KVM都是完整的操作系统所以我们直接用[第4讲](https://time.geekbang.org/column/article/356789)中的node\_exporter就可以完全覆盖。但是往上一层的Kubernetes我们怎么才能全面监控呢这里就涉及到Kubernetes的监控套件了。现在我们来看一个Kubernetes全局监控套件如下所示
![](https://static001.geekbang.org/resource/image/cf/c3/cf1cfd1bf86c4b5c43e5a3e61f02b4c3.png)
![](https://static001.geekbang.org/resource/image/b7/10/b7f08283d7e4a889e68d0112437ed310.png)
类似这样的模板有很多我就不一一列举了。虽然各个工具展示的方式不同但都能达到我们全局监控Kubernetes的目标。所以我们只需要选择一个合适自己业务系统的Kubernetes监控套件就可以了。
其实,如何选择一个监控套件来实现各层的监控需求,是全局监控的一个难点。在全局监控中,我一直在强调一个词——“分层”。因为在我参与过的项目中,经常有人说:“我们的监控是全的。”但当我自己动手查看时,只看到操作系统级的数据,而其上运行的其他内容就没有了。
还有一个我亲身经历的例子。我在给一个金融机构做培训时,他们说线上有问题,让我帮着分析一下。同时,他们还胸有成竹地跟我说:“我们的监控数据是很全的,只是不知道问题在哪里。”
可是我拿过数据一看发现没有Java线程级的数据他们的监控平台也不支持细化到线程级。而从系统的数据来看这恰巧又是一个线程的问题。于是他们就只有重新采集数据。等数据再拿过来问题在哪里一目了然。
这就是全局监控数据缺失,进而导致分析链路断裂的典型例子。所以,全局监控的完整性是性能分析非常重要的部分。
* **定向监控策略和工具选型**
完成了全局监控之后性能场景就可以运行起来了。但是当我们遇到问题时我们在全局监控数据中就只能看到第一层的计数器比如说CPU高、内存不足、IO高、网络带宽大等信息。从这些信息中我们无法知道做什么样的优化才能使CPU降下来、内存使用变少、IO变低、网络变小。
所以这时候我们必须要做定向监控定向监控就是为了寻找更细节的证据。在RESAR性能工程中我之所以把数据分为全局和定向是因为性能分析是有逻辑链路的。如果不做区分只是一股脑地全看会让你有一种数据很多但不知道哪个是关键数据的感觉。
请你注意,在我的分析理念中,全局和定向是必须分开的。因为对于全局监控数据,我们会一直采集并保存一段时间,这样对系统整体的性能影响并不大。可是,如果我们对定向数据也一直采集的话,就会影响系统整体的性能,比如说线程栈的数据采集、对象的内存消耗采集等等,这些操作其实对性能都有影响,不管工具厂商吹嘘得有多完美,我们在实践中已经有足够的数据可以证明这一点。
不过当前市场上的很多监控工具是不区分全局监控和定向监控的。所以在我们前面罗列的全局监控工具中你也可以看到定向监控需要的数据。比如说我们在用JvisualVM监控Java的时候不仅能看到CPU、JVM、Class、Thread等全局信息也能看到栈、方法、对象等定向信息。
对于Java微服务应用我们用表格中列出的工具其实就可以看到比较细节的数据了。像方法级、对象级这些Spring Boot Admin、JvisualVM和其他的一些JDK自带的监控工具等都可以做到。如果我们在使用中觉得哪里不足还可以再考虑其他的定向监控工具。
而有了对Spring Cloud微服务的监控工具之后在提供服务的过程中我们需要看到的是业务链路这时上面的对单个微服务进行监控的工具就做不到了。
所以这里我用APM工具SkyWalking来链路的监控。
在SkyWalking中我们不仅能看到链路图也可以用它看到更细化的数据。这张图就是SkyWalking中的链路图我把它定义为全局监控。
![](https://static001.geekbang.org/resource/image/90/fb/90e0794b86b07c6a8991f27cc776f5fb.png)
下面这张图是用SkyWalking工具看到的更细化的数据我把这样的数据定义为定向监控数据。
![](https://static001.geekbang.org/resource/image/74/5d/7470ab205c982e07bd36a38d1bca405d.png)
这个图展示的是定向分析的一个中间环节。我们从图中可以看到一个请求对应的每一段的耗时比如说一个接口调用另一个接口、JDBC、Redis等后续组件。当我们发现哪一段耗时比较长的时候就可以到耗时长的那个组件上根据定向监控的数据接着往下分析了。
通过上述内容,我们知道了在定向监控时需要哪些数据。所以在我们分析完系统架构之后,也要对定向监控工具进行选型,把需要的工具都准备好,以免出现有问题时无工具可用的情况。不过,**定向监控只是先准备好,不用一开始就使用**,这一点你要切记。
在这里,我列出了在我们这个示例系统中可能会用到的定向分析工具,我主要考虑是覆盖系统级、代码级、数据库级和缓存级。
![](https://static001.geekbang.org/resource/image/c6/af/c6b0c37d90c86241c7857d798aa45baf.jpg)
这样一来,我们在后续的性能分析工作中,就不用再临时抓瞎到处找工具了。
## 总结
在我的逻辑中,全局和定向必须要分开,这一点我在前面跟你强调过,不分开就会导致资源浪费,并且我们需要的数据还有可能是缺失的。
另外,请你注意,监控的全面性直接取决于项目级性能分析决策树的构建,也就是说用什么工具并不是关键,关键在于这些监控工具有没有把性能分析决策树的树叶都覆盖全。
在选择监控工具时,我们主要考虑的是成本、范围、层次、使用的延续性等因素。只有合理的监控策略和监控工具,才能让性能分析决策树真地落地,才能让性能瓶颈证据链的查找具有可能性。
最后,我还想提醒你一点,请不要认为监控到技术组件这个层级就足够了,把对应技术组件的模块和模块对应的计数器都覆盖到才是重要的。因为在分析瓶颈的过程中,我们要找到计数器之间的关联性,如果有一个计数器缺失,就会导致分析中断。
## 课后作业
这就是今天的全部内容,我给你留了两道题以巩固今日所学,请你思考一下:
1. 如何判断自己选择的性能监控工具,有没有覆盖全性能分析决策树?
2. 为什么不建议选择更多的定向监控分析工具?
记得在留言区和我讨论、交流你的想法,每一次思考都会让你更进一步。
如果这节课让你有所收获,也欢迎你分享给你的朋友,共同学习进步。我们下一讲再见!