背景线上环境Jenkinsjob拉起slaveVM通过master机器运行。在实际使用中,作业的CPU使用率偶尔会瞬间升高,导致作业被系统杀死。现象我们的PR会自动触发jenkinsjob,job的主要内容是:编译,单元测试,打包。编译阶段一般都能正常通过,因为我们的项目比较大,所以给出的MAVEN-OPT是比较充足的:4g堆内存,1g初始元空间。单元测试是通过mavensurefire插件完成的。运行过程中CPU会暴涨,然后会出现GCoverheadexceedlimitaion异常或者直接显示killed(可以确认不是人为killed)。排查这个问题时有发生,有时出现后会持续好几天。距离上次发生已经半年多了。当时我跟平台组伙伴一起考察。通过top命令可以看到,执行到某一步时,CPU占用突然出现。暴涨,然后进程终止。当时根据提示的原因,怀疑是GC的问题,所以一开始就不断的增加内存,希望通过资源来解决问题,但是不管是内存增加一倍还是三倍,这是行不通的。VM启动内存已经增加到12G,还是不能解决问题。接下来观察发现问题出现的时间点是fork动作的时候。这里简单介绍一下mavensurefire插件的工作过程。这个插件在运行单元测试时通过forkVM运行。我们项目中的配置如下:1Concetrue-Xverify:none-Xms512m-Xmx512m有一个这里的重要参数:forkCount,如果是纯数字,则启动相应数量的VM。如果以C结尾,则根据(本机CPU核数*前面的个数)启动相应数量的VM。当时平台组成员登录jenkinsVM看到在fork运行的瞬间,分叉出了16个单元测试VM,每个VM有0.5G的空间。如果加上metaspace等其他空间,那是一个很高的数字,尤其是fork之后马上就会有单元测试跑起来。如果UT本身占用的空间比较大,可以预见此时GC会很高,所以我觉得可以尝试通过减少forkCount,增加每个fork产生的VM的大小来解决问题。所以把forkCount从1C改成0.5C,把512m改成1g。从总量来看,消耗的空间和修改前一样,但是因为减少了vm,更多的空间给了UT,更少的VM意味着更少的UT同时运行,所以GC的频率应该减少一些。尝试新的配置后,发现问题确实解决了,直到最近作业一直运行的很流畅。又碰巧最近修改了代码,升级了依赖包。因为这个依赖包中有大量的第三方依赖,而且包本身的代码量也在快速增加,所以升级后又出现了之前的问题,问题的表现也基本一样。不同的是,这次问题不是在fork的时候出现的,而是随时出现的。.一开始以为可以继续减少forkCount来解决问题,把forkCount改成一个固定的数字:4,也就是每次只启动4个VM跑UT,无效。然后尝试增加VMfromfork的空间,从1G增加到2G(机器VM是12G),还是不行。本地使用类似的配置甚至更低的配置都可以成功运行,但此时我毫无头绪。平台组成员只能在登录VM时看到CPU占用率高,但无法确定GC发生的位置。在jenkins页面发呆的时候,突然看到了ThreadDump的按钮。我点击它并尝试了它。结果jenkinsVM的threaddump居然被dump了。马上用fastthread.io分析了一下,发现在maven的cli中有一个类DefaultMirrorSelector的方法:stackTrace:java.lang.Thread.State:RUNNABLEatjava.lang.String.substring(String.java:1969)atjava.lang.String.split(String.java:2353)在java中。lang.String.split(String.java:2422)在org.eclipse.aether.util.repository.DefaultMirrorSelector.matchesType(DefaultMirrorSelector.java:206)在org.eclipse.aether.util.repository.DefaultMirrorSelector.findMirror(DefaultMirrorSelector.java:101)在org.eclipse.aether.util.repository.DefaultMirrorSelector.getMirror(DefaultMirrorSelector.java:59)在org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager.aggregateRepositories(DefaultRemoteRepositoryManager.java:155)在多个转储中process一直在占用大量CPU,这时候才怀疑maven。我将它与本地maven版本进行了比较。本地版本为3.6.0,在线版本为3.3.9。平台组的成员尝试使用3.6.0版本的maven搭建新的jenkinspipeline,尝试搭建。成功了!至此,问题基本确定,是maven低版本的问题。总结一下,jenkins的报错信息有误导,误以为是GC的问题,但是通过threaddump发现CPU暴增其实是maven的问题,所以多做几次threaddump总是对的首先在分析这个CPUsurge问题的时候。