我们对一个多线程系统通常需要知道:
- 系统的瓶颈所在
- 系统性能表现不佳(如响应慢、吞吐低)时如何优化
先做一个类比
某技术团队
- 由100个开发人员组成
- 每个开发人员接到任务之后,都会按如下流程进行工作:
- 技术评审会
- 构思解决方案
- coding
- 测试
- bugfix
- merge代码
- 上线
那么,管理者如何找到此团队效率的瓶颈所在呢?方法很简单:
假设管理者有一部神奇的照相机,能同时将100名开发人员拍下来
在拍照之后,管理者将100名开发人员正在做的事记录下来,做整理后得到:
人数 工作内容
10 技术评审会
5 构思解决方案
15 coding
12 测试
8 bugfix
38 merge代码
12 上线-
很显然,管理者可以直接得出结论:
merge代码是当前团队的主要瓶颈,且约占整体时间的38 / 100 = 38% 员队人数越多时这个比例估算的越准确
至于瓶颈是否合理,是否需要优化,就交给该管理者去做好了,我们回到主题
可见,拥有一部神奇的照相机是非常牛逼的
-
对上面的技术团队而言:
用一部神奇相机记录下某一瞬间所有人在做的事情,并统计他们各自在做些什么 然后找到哪件事在做的人最多,从而知道团队效率的问题所在
-
对一个多线程系统而言:
将服务暂停,并将所有线程正在做的事情dump下来后再让服务继续,统计所有线程的逻辑,从而知道性能瓶颈所在
是不是很想拥有此技能?其实很简单,现有的工具就可以帮助你做到这一点:
- jstack:适用于java进程,可以取到所以线程的堆栈dump
- pstack:适用于所有linux进程,是对gdb的功能封装
实践示例
实践要点
- 此方法能定位大多常见的性能问题,但不要迷信
- 取stack dump会导致服务有一定时间的暂停,但通常较快,可以对线上服务执行
- 一些方法调用耗时较小时,取stack dump可能是抓不到的
- 可以给系统较大的压力以使得更多线程在处理任务,此时用本文方法会更加快速准确
- 需要注意:同一个系统在不同的压力下,瓶颈点可能不同
- jstack/pstack工具仅会给出dump的内容,而不会做统计,而dump的内容可能有几万行,查看起来不太方便。因此我写了个脚本用来做统计处理,可参考使用,欢迎提交PR