第十二章:故障排除
Jenkins 常见问题诊断和解决方案,包括性能问题、插件故障、网络问题。
最后更新: 2024-01-15
页面目录
故障排除
本章汇总 Jenkins 使用中的常见问题及其解决方案,帮助您快速定位和解决问题。
诊断工具
1. Jenkins 日志
# Docker 环境查看日志
docker logs jenkins
# Linux 环境日志位置
sudo tail -f /var/log/jenkins/jenkins.log
# systemd 日志
sudo journalctl -u jenkins -f
2. 脚本控制台
Jenkins → 系统管理 → 脚本命令行
// 查看系统信息
println "Jenkins Version: ${Jenkins.instance.version}"
println "Java Version: ${System.getProperty('java.version')}"
println "OS: ${System.getProperty('os.name')} ${System.getProperty('os.version')}"
println "Jenkins Home: ${Jenkins.instance.rootDir}"
// 查看插件状态
Jenkins.instance.pluginManager.plugins.each { plugin ->
println "${plugin.shortName}: ${plugin.version} (${plugin.active ? 'active' : 'inactive'})"
}
// 查看节点状态
Jenkins.instance.computers.each { computer ->
println "Node: ${computer.displayName}, Offline: ${computer.isOffline()}"
}
3. 系统信息
系统管理 → 系统信息
• Java 系统属性
• 环境变量
• 内存信息
• 插件列表
常见问题与解决方案
问题 1:Jenkins 启动失败
症状
Jenkins does not start
诊断步骤
# 1. 检查 Java 版本
java -version
# 2. 检查端口占用
sudo netstat -tlnp | grep 8080
# 或
sudo lsof -i :8080
# 3. 检查磁盘空间
df -h
# 4. 检查权限
ls -la /var/lib/jenkins
ls -la /var/log/jenkins
# 5. 查看启动日志
sudo cat /var/log/jenkins/jenkins.log
解决方案
# 端口被占用 - 修改端口
sudo vi /etc/default/jenkins
# 修改 HTTP_PORT=8081
# 磁盘空间不足 - 清理
sudo apt clean
docker system prune -a
sudo rm -rf /tmp/*
# 权限问题 - 修复权限
sudo chown -R jenkins:jenkins /var/lib/jenkins
sudo chown -R jenkins:jenkins /var/log/jenkins
# 内存不足 - 增加内存
sudo vi /etc/default/jenkins
# 添加: JAVA_OPTS="-Xmx2g -Xms1g"
问题 2:构建卡在等待中
症状
Build is queued, waiting for an available executor
诊断步骤
1. 检查系统管理 → 节点管理
2. 查看是否有可用节点
3. 检查 Executor 是否都忙碌
4. 查看构建队列长度
解决方案
// Pipeline 中优化资源使用
pipeline {
agent {
label 'docker'
customWorkspace '/tmp/build-${BUILD_NUMBER}'
}
options {
// 设置合理的超时
timeout(time: 30, unit: 'MINUTES')
// 避免并发冲突
disableConcurrentBuilds()
}
stages {
// 快速失败
stage('Quick Check') {
steps {
script {
if (!fileExists('pom.xml')) {
error 'Build file not found'
}
}
}
}
}
}
问题 3:Agent 连接失败
症状
Agent is disconnected
诊断步骤
# 1. 检查 Agent 服务状态
sudo systemctl status jenkins-agent
# 2. 检查网络连通性
telnet jenkins-master 50000
# 3. 检查防火墙
sudo ufw status
# 4. 检查 Agent 日志
sudo cat /var/log/jenkins/agent.log
解决方案
# 重新注册 Agent
# 1. 生成新的 agent.jar
curl -O http://jenkins:8080/jnlpJars/agent.jar
# 2. 启动 Agent
java -jar agent.jar \
-jnlpUrl http://jenkins:8080/computer/${NODE_NAME}/slave-agent.jnlp \
-secret ${AGENT_SECRET} \
-workDir "/opt/jenkins/agent"
问题 4:Git 克隆失败
症状
Failed to connect to repository
stderr: Permission denied (publickey)
诊断步骤
# 1. 测试 SSH 连接
ssh -T git@github.com
ssh -vT git@github.com # 详细日志
# 2. 检查 SSH 密钥
ls -la ~/.ssh/
# 3. 检查 known_hosts
cat ~/.ssh/known_hosts
解决方案
# 生成新 SSH 密钥
ssh-keygen -t ed25519 -C "jenkins@server"
cat ~/.ssh/id_ed25519.pub
# 添加到 GitHub/GitLab
# 测试密钥
ssh -T git@github.com
# 检查 Jenkins 凭据
# 系统管理 → 安全 → Manage Credentials
# 验证 SSH 密钥凭据
// Pipeline 中指定凭据
pipeline {
stages {
stage('Checkout') {
steps {
git {
remote {
url 'git@github.com:org/repo.git'
credentialsId 'github-ssh-key'
}
branch 'main'
}
}
}
}
}
问题 5:插件安装失败
症状
Failed to install plugin
诊断步骤
# 1. 检查网络
curl -I https://updates.jenkins.io/current/
# 2. 检查磁盘空间
df -h /var/lib/jenkins
# 3. 检查权限
ls -la /var/lib/jenkins/plugins/
解决方案
# 手动安装插件
# 1. 下载插件 .hpi 文件
curl -O https://updates.jenkins.io/current/plugins/git/latest/git.hpi
# 2. 复制到插件目录
sudo cp git.hpi /var/lib/jenkins/plugins/
# 3. 重启 Jenkins
sudo systemctl restart jenkins
# 修复插件目录权限
sudo chown -R jenkins:jenkins /var/lib/jenkins/plugins/
问题 6:内存溢出 (OOM)
症状
java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: GC overhead limit exceeded
诊断步骤
# 查看 JVM 内存使用
jstat -gc <pid>
jmap -heap <pid>
# 检查 Jenkins 日志中的 OOM
grep -i "outofmemory" /var/log/jenkins/jenkins.log
解决方案
# 增加 JVM 内存
# /etc/default/jenkins
JAVA_ARGS="-Xmx4g -Xms2g -XX:+UseG1GC -XX:MaxMetaspaceSize=512m"
# Pipeline 中优化
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-11'
jvmArgs '-Xmx1g'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -M512m clean package' # 限制 Maven 内存
}
}
}
}
问题 7:构建产物无法归档
症状
'archiveArtifacts' not executed
解决方案
pipeline {
post {
success {
// ✅ 在 success 或 always 中归档
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
stages {
stage('Build') {
steps {
// ✅ 确保产物存在
sh '''
mvn clean package
ls -la target/*.jar
'''
}
}
}
}
问题 8:凭据无法解密
症状
Failed to decrypt credentials
诊断
// 脚本控制台
import hudson.util.Secret
import jenkins.model.Jenkins
// 测试解密
try {
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials.class,
Jenkins.instance
)
creds.each { c ->
println "${c.id}: ${c.username}"
}
} catch (Exception e) {
println "Error: ${e.message}"
}
解决方案
# 检查 secrets 目录
ls -la /var/lib/jenkins/secrets/
# 修复权限
sudo chown -R jenkins:jenkins /var/lib/jenkins/secrets/
sudo chmod 700 /var/lib/jenkins/secrets/
sudo chmod 600 /var/lib/jenkins/secrets/*
# 重启 Jenkins
sudo systemctl restart jenkins
性能问题排查
构建缓慢
// Pipeline 中添加时间戳
pipeline {
options {
timestamps()
}
stages {
stage('Build') {
steps {
timeStamp() {
sh 'mvn clean package -DskipTests'
}
}
}
}
}
常见性能瓶颈
| 瓶颈 | 症状 | 解决方案 |
|---|---|---|
| 网络 I/O | 依赖下载慢 | 使用 Nexus/Artifactory |
| 磁盘 I/O | 文件读写慢 | 使用 SSD |
| 内存不足 | GC 频繁 | 增加内存 |
| CPU 过载 | 构建排队 | 增加 Executor |
| 数据库 | 查询慢 | 使用外置数据库 |
调试技巧
1. 启用详细日志
系统管理 → 日志记录
添加记录器:
• hudson.model.Job: ALL
• hudson.plugins.git: ALL
• org.jenkinsci.plugins: ALL
2. Pipeline 调试
pipeline {
stages {
stage('Debug') {
steps {
script {
echo "Build Number: ${env.BUILD_NUMBER}"
echo "Workspace: ${env.WORKSPACE}"
echo "Branch: ${env.BRANCH_NAME}"
sh 'printenv | sort'
sh 'ls -la'
}
}
}
}
}
3. 使用 sh scriptExitCode
steps {
script {
def result = sh(
script: 'mvn test',
returnStatus: true,
returnStdout: true
)
echo "Exit code: ${result}"
if (result != 0) {
echo "Build failed with exit code ${result}"
}
}
}
常见错误码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| 0 | 成功 | - |
| 1 | 一般错误 | 检查日志 |
| 126 | 权限不足 | chmod +x |
| 127 | 命令不存在 | 检查 PATH |
| 137 | OOM kill | 增加内存 |
| 143 | 被信号终止 | 检查超时 |
恢复操作
Jenkins 无法启动时的紧急恢复
#!/bin/bash
# emergency-recovery.sh
set -e
echo "=== Jenkins 紧急恢复 ==="
# 1. 备份当前配置
cp -r /var/lib/jenkins /var/lib/jenkins.bak.$(date +%Y%m%d)
# 2. 检查端口
sudo netstat -tlnp | grep 8080 || echo "Port 8080 is free"
# 3. 检查 Java
java -version
# 4. 检查日志
tail -100 /var/log/jenkins/jenkins.log
# 5. 清除缓存
rm -rf /var/lib/jenkins/cache/
rm -rf /var/lib/jenkins/temp/
# 6. 重置插件(如果需要)
# mv /var/lib/jenkins/plugins /var/lib/jenkins/plugins.bak
# 7. 启动 Jenkins
sudo systemctl start jenkins
# 8. 验证
sleep 10
curl -f http://localhost:8080 || echo "Jenkins is not responding"
获取帮助
| 资源 | 链接 |
|---|---|
| 官方文档 | https://www.jenkins.io/doc/ |
| 问题追踪 | https://issues.jenkins.io/ |
| Slack | https://jenkins.io/slack/ |
| Wiki | https://wiki.jenkins-ci.org/ |
| Stack Overflow | https://stackoverflow.com/questions/tagged/jenkins |
下一步
最后,让我们学习如何开发自定义 Jenkins 插件。
👉 插件开发
🔧 提示:遇到问题时,先查看日志和系统信息,通常能快速定位原因。