【瞬时视角】使用jstack/pstack定位服务端性能问题

我们对一个多线程系统通常需要知道:

  • 系统的瓶颈所在
  • 系统性能表现不佳(如响应慢、吞吐低)时如何优化

先做一个类比

某技术团队

  • 由100个开发人员组成
  • 每个开发人员接到任务之后,都会按如下流程进行工作:
  1. 技术评审会
  2. 构思解决方案
  3. coding
  4. 测试
  5. bugfix
  6. merge代码
  7. 上线

那么,管理者如何找到此团队效率的瓶颈所在呢?方法很简单:

  1. 假设管理者有一部神奇的照相机,能同时将100名开发人员拍下来

  2. 在拍照之后,管理者将100名开发人员正在做的事记录下来,做整理后得到:
    人数 工作内容
    10 技术评审会
    5 构思解决方案
    15 coding
    12 测试
    8 bugfix
    38 merge代码
    12 上线

  3. 很显然,管理者可以直接得出结论:

     merge代码是当前团队的主要瓶颈,且约占整体时间的38 / 100 = 38%
     员队人数越多时这个比例估算的越准确
    

至于瓶颈是否合理,是否需要优化,就交给该管理者去做好了,我们回到主题

可见,拥有一部神奇的照相机是非常牛逼的

  • 对上面的技术团队而言:

      用一部神奇相机记录下某一瞬间所有人在做的事情,并统计他们各自在做些什么
      然后找到哪件事在做的人最多,从而知道团队效率的问题所在
    
  • 对一个多线程系统而言:

      将服务暂停,并将所有线程正在做的事情dump下来后再让服务继续,统计所有线程的逻辑,从而知道性能瓶颈所在
    

是不是很想拥有此技能?其实很简单,现有的工具就可以帮助你做到这一点:

  • jstack:适用于java进程,可以取到所以线程的堆栈dump
  • pstack:适用于所有linux进程,是对gdb的功能封装

实践示例

  • 缓存策略优化
  • ThreadPoolExecutor使用错误导致死锁

实践要点

  • 此方法能定位大多常见的性能问题,但不要迷信
  • 取stack dump会导致服务有一定时间的暂停,但通常较快,可以对线上服务执行
  • 一些方法调用耗时较小时,取stack dump可能是抓不到的
  • 可以给系统较大的压力以使得更多线程在处理任务,此时用本文方法会更加快速准确
  • 需要注意:同一个系统在不同的压力下,瓶颈点可能不同
  • jstack/pstack工具仅会给出dump的内容,而不会做统计,而dump的内容可能有几万行,查看起来不太方便。因此我写了个脚本用来做统计处理,可参考使用,欢迎提交PR

你可能感兴趣的:(【瞬时视角】使用jstack/pstack定位服务端性能问题)