一. 背景:
新功能上线后异步任务忽然阻塞了,造成所有的任务都在执行中很久都没有结果。而且整个服务接口都很慢。
二. 排查过程:
-
发现报错任务队列已经满了,不能再接受任务
检查后发现,除异步任务外很多定时任务都加了@Async注解,所以给该异步任务新写一个任务池ExecutorTaskPool。
-
修改后上线,发现会快一点,没有报错,但是依然阻塞。效果不理想。
对比新老版本,发现上线了一个新功能,该功能增加了一个定时任务为每30秒钟执行一次,并且每次都是以线程的方式执行任务大约有几百个任务。所以推断是该功能导致,一直占用资源导致异步任务阻塞,无法执行。所以将该功能暂时关闭掉。
同时,发现gc很频繁,每秒钟四五次。
根据gc日志计算后得出,16g的堆新生代只有600M,新生代太小造成gc频繁。
本来想根据jmap -heap pid看到是否与推算一致,但是发现jdk版本有问题导致该命令报错
所以使用 jstat -gccapacity pid
得出,新生代66M 老年代 15.4g分配及其不合理。所以将新生代调整为5g -Xmn5g。
修改后,异步任务正常,其他接口也都正常。