Jenkins调优实践
最近一段时间,Jenkins频繁发生FULL GC,耗时在1分钟左右,导致jenkins在1分钟内无法响应任何请求,影响到用户使用。
现象:
从GC日志看,就是在某段时间出现大量对象,且存活时间较长,导致无法回收掉,内存紧张最终触发了长耗时的FULL GC.
调优过程:
第一轮调优:
最后jvm运行参数:
-Xms40G -Xmx40G -XX:+UseG1GC -XX:+UseStringDeduplication -javaagent:/data/soft/jmx/statistic-agent-entry-2.0.0.jar -XX:MaxGCPauseMillis=400 -XX:ConcGCThreads=6 -XX:MarkStackSize=8388608 -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/data/logs/jenkins/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=15 -XX:GCLogFileSize=2M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/jenkins/jenkins.hprof
以上主要工作,跟内存紧密相关的就是红框标识的,即“记录并展现构建结果”。其他的跟内存关系不大。
二:常驻内存是什么数据?
通过上一步的分析,其实已经有答案了。这一步只是验证。因产线堆内存大(40G)。所以,不可能在发生OOM的时候,把堆dump下来分析,没有那么大的机器去分析。只能做采样分析,在晚上21:30对堆做了dump分析。通过分析堆,得到堆里的主要内存确实是日志信息,如下:
以上截图是通过heapHero生成。heapHero是一个堆分析工具。
三:如何彻底解决?
单一master的容量总是有上限的,随着构建任务的不断增加,并发量的增大,master终有hold不住的一天,这和软件架构从单一架构向分布式架构转换的道理是一样的。这套jenkins内存消耗高确实是因为构建的量大,jenkins本身并无异常。如果增加配置和调优后仍然无法满足日常的构建需求,建议剥离部分构建作业到新的master/slave集群,分摊压力。
参考资料:
https://www.edureka.co/blog/jenkins-master-and-slave-architecture-a-complete-guide/
https://www.jenkins.io/doc/book/managing/nodes/
- 扩大内存。原来堆内存28G,扩到了30G。
- 预留堆内存buffer,对抗突发流量。
- 调高GC吞吐量,让一次GC尽可能的多回收垃圾。
- 增加GC线程,加快回收效率,并让Mix GC提早回收老年代。
- 增加JVM监控,便于观察JVM的行为变化。