记一次印象深刻的Bug/故障

起因

在禅道上收到项目组提的一个故障:有一个业务接口,偶尔查不出数据,其它接口数据都正常,找不出原因,请求平台帮助排查。

项目架构介绍

springcloud微服务项目

注册中心:eureka

数据库:oracle

缓存:redis

orm:springJPA

反向代理:nginx

网关:zuul

容器化技术:docker

容器编排管理:k8s

CD/CI流水线:jenkins

排查过程

1.首先查看了服务器的日志信息,没有异常。


2.本地启了服务本地debug发现无法复现问题。(本地无法复现是很难受的,懂的都懂)


3.怀疑是注册中心注册了非法服务,导致请求轮询的时候轮询到非法服务查询到其他数据库,检查发现无其他非法服务被注册。


4.检查每个服务配置的数据库信息是否一致,检查结果数据库是一致的。(排查到这一步没发现异常,多少有点心灰意冷)


5.观察代码,无意中发现该业务接口使用了多线程,并且项目里有两个线程池,一个业务短信的线程池(标注了@Primary注解),一个专门给流程使用的线程池(没标注@Primary注解)。但是引入TaskExecutor的时候并没有指定name,导致系统内所有的业务都使用了同一个线程池,该线程池配置的最大线程数为16,最大队列数为64,线程池的拒绝策略为CallerRunsPolicy(由调用者处理,这也是日志没报错的原因)。

顺着思路,去服务器通过jps(ps -ef也行)命令查找到业务的进程pid,再通过top -Hp pid 查看到有大量的GC线程和短信线程一直执行,线程总数已超过了80个,导致后面发起的新线程不做任何处理。


6.要求项目组检查代码质量问题,然后检查短信发不出去的问题,最终问题得以解决。

猜你喜欢

转载自blog.csdn.net/qq_42014561/article/details/131638289