最近在团队内部做Jenkins持续集成时遇到一个诡异现象:构建日志明明显示"SUCCESS",但最终生成的部署包却缺少部分文件。更奇怪的是,在构建日志末尾出现了"Killed"字样。这种情况在资源受限的构建服务器上尤其常见,特别是当项目规模增长到一定程度后。
我最初以为是构建脚本有问题,但反复检查后确认脚本逻辑完整。后来通过分析系统日志和Jenkins控制台输出,发现这是Linux内核的OOM Killer(Out-Of-Memory Killer)机制在作祟。当系统内存不足时,内核会强制终止消耗内存最多的进程,而Jenkins构建进程往往就是"受害者"。
关键提示:不要被表面的"SUCCESS"迷惑,当发现产物不全时,一定要检查完整日志内容,特别是结尾处的隐藏信息。
Linux系统在内存不足时,会根据进程的oom_score值选择终止目标。计算规则包括:
可以通过以下命令查看进程的OOM评分:
bash复制cat /proc/[PID]/oom_score
在以下构建场景中特别容易触发OOM:
这是因为OOM Killer是直接发送SIGKILL信号(信号编号9)终止进程,该信号不能被捕获或忽略。Jenkins只能检测到进程异常退出,但无法判断具体原因,因此仍会标记为成功。
bash复制grep -i 'killed process' /var/log/syslog
bash复制# 安装sysstat后使用
sar -r -f /var/log/sa/sa[日期]
bash复制sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
groovy复制pipeline {
agent any
environment {
MAVEN_OPTS = '-Xmx2048m -XX:MaxPermSize=512m'
}
stages {
stage('Build') {
steps {
sh 'mvn clean package -T 1C' // 限制线程数
}
}
}
}
dockerfile复制FROM maven:3.8-jdk-11
ENV MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m"
在Jenkinsfile中添加资源监控步骤:
groovy复制stage('Monitor') {
steps {
sh '''
free -h
top -bn1 | head -5
'''
}
}
调整进程的oom_score_adj值(值越小越不容易被杀死):
bash复制echo -1000 > /proc/[PID]/oom_score_adj
我在实际运维中总结的经验法则是:当项目构建时间超过10分钟或日志超过5000行时,就需要特别关注内存使用情况。一个实用的检查清单:
最后分享一个实用命令,可以快速统计构建产物的完整性:
bash复制find target/ -type f | wc -l # 对比正常构建时的文件数量