赞
踩
前段时间我们接入了 ELK 公司出品的 Elastic-APM 作为全链路监控平台,终结了我好几年前撸的字节码注入全链路监控平台。前段时间有一个业务在启动过程中,会概率性出现大量线程阻塞,导致可对外提供服务的 HTTP 线程非常少,流量进来以后马上出现 HTTP 线程耗尽,健康检查接口请求失败,服务被 k8s 杀死。
既然是线程的问题,当然想到的是 dump 线程堆栈,人肉阅读也可以,上传到 PerfMa XSheepdog 会更加简单。在锁的这一栏的截图如下所示。
可以看到 http-nio-18880-exec-44 线程持有了一个锁,这个锁被其它的 199 个线程等待。持有锁的线程堆栈如下图所示。
上层的调用方法是 co.elastic.apm.agent.bci.ElasticApmAgent#ensureInstrumented,这段逻辑背后是在调用 bytebuddy 利用 ASM 进行 class 的转换注入。
等待锁的线程恰好 block 也在这个方法,如下图所示。
通过堆栈分析,这个问题的出现与我们业务代码用了 ParallelStream 有关。Java 中的 Stream 是一个比较好用的东西,在函数式编程、流式数据处理上写起来比较简单。除了串行化的流式处理,Java 也提供了并行流 parallelStream 可以使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。