如何让systemd检测到Jenkins Agent故障并重启进程?
让systemd检测Jenkins Agent异常并重启的解决方案
针对Jenkins Agent因ClosedChannelException断开连接但主进程未退出,导致systemd无法自动重启的问题,可通过以下几种方案解决:
方案一:添加健康检查脚本,让systemd基于Agent状态重启
1. 编写Agent健康检查脚本
创建/usr/local/bin/check_jenkins_agent.sh脚本,通过Jenkins API验证Agent在线状态:
#!/bin/bash # 替换为你的Jenkins配置信息 JENKINS_URL="http://你的Jenkins控制器地址" AGENT_NAME="你的Agent节点名称" # 若Jenkins开启权限验证,需填写管理员账号和API Token ADMIN_USER="管理员账号" API_TOKEN="管理员API Token" # 调用Jenkins API获取Agent离线状态 AGENT_OFFLINE=$(curl -s -u "${ADMIN_USER}:${API_TOKEN}" "${JENKINS_URL}/computer/${AGENT_NAME}/api/json" | jq -r '.offline') # 若Agent离线,返回非0状态码触发systemd重启 if [ "${AGENT_OFFLINE}" = "true" ]; then exit 1 else exit 0 fi
给脚本添加执行权限:
chmod +x /usr/local/bin/check_jenkins_agent.sh
2. 修改systemd服务配置
编辑你的Jenkins Agent服务文件(如/etc/systemd/system/jenkins-agent.service),添加健康检查和重启策略:
[Unit] Description=Jenkins Agent Service After=network.target [Service] User=jenkins Group=jenkins # 原有Agent启动命令保留 ExecStart=/usr/bin/java -jar /path/to/agent.jar -url http://你的Jenkins控制器地址 -secret 你的Agent密钥 -name 你的Agent节点名称 # 启动后立即执行一次健康检查 ExecStartPost=/usr/local/bin/check_jenkins_agent.sh # 后台启动定时健康检查(每5分钟执行一次) ExecStartPost=/bin/bash -c "while true; do sleep 300; /usr/local/bin/check_jenkins_agent.sh || exit 1; done &" # 配置重启策略:检查失败或进程异常时重启 Restart=on-failure RestartSec=5 # 确保进程退出时清理子进程 KillMode=process [Install] WantedBy=multi-user.target
重新加载systemd配置并重启服务:
systemctl daemon-reload systemctl restart jenkins-agent.service
方案二:监控Agent日志,捕获异常后终止进程
通过监控Agent日志中的特定异常信息,主动终止Java进程,触发systemd重启:
1. 编写日志监控启动脚本
创建/usr/local/bin/start_jenkins_agent.sh:
#!/bin/bash AGENT_JAR_PATH="/path/to/agent.jar" JENKINS_URL="http://你的Jenkins控制器地址" AGENT_SECRET="你的Agent密钥" AGENT_NAME="你的Agent节点名称" LOG_PATH="/var/log/jenkins-agent.log" # 启动Agent并后台运行 java -jar "${AGENT_JAR_PATH}" -url "${JENKINS_URL}" -secret "${AGENT_SECRET}" -name "${AGENT_NAME}" > "${LOG_PATH}" 2>&1 & AGENT_PID=$! # 实时监控日志,捕获ClosedChannelException后终止进程 tail -f "${LOG_PATH}" | while read -r line; do if echo "${line}" | grep -q "java.nio.channels.ClosedChannelException"; then kill "${AGENT_PID}" exit 1 fi done
添加执行权限:
chmod +x /usr/local/bin/start_jenkins_agent.sh
2. 更新systemd服务配置
修改服务文件中的ExecStart指向该脚本:
[Service] # 替换原有ExecStart为以下内容 ExecStart=/usr/local/bin/start_jenkins_agent.sh Restart=on-failure RestartSec=5
重新加载配置并重启服务:
systemctl daemon-reload systemctl restart jenkins-agent.service
方案三:基于网络连接状态监控
通过检查Agent与Jenkins控制器的WebSocket连接是否存在,判断Agent是否正常运行:
1. 编写连接检查脚本
创建/usr/local/bin/check_agent_connection.sh:
#!/bin/bash # 替换为Jenkins控制器的IP和端口 JENKINS_IP="192.168.1.100" JENKINS_PORT="8080" while true; do sleep 60 # 检查是否存在Agent到控制器的ESTABLISHED状态连接 CONN_COUNT=$(ss -tunap | grep java | grep "${JENKINS_IP}:${JENKINS_PORT}" | grep -c ESTABLISHED) if [ "${CONN_COUNT}" -eq 0 ]; then pkill -f "agent.jar" exit 1 fi done
添加执行权限:
chmod +x /usr/local/bin/check_agent_connection.sh
2. 更新systemd服务配置
在服务文件中添加该脚本作为后台检查:
[Service] # 原有配置保留 ExecStartPost=/usr/local/bin/check_agent_connection.sh & Restart=on-failure RestartSec=5
重新加载配置并重启服务。
内容的提问来源于stack exchange,提问作者vishpat
相关产品推荐
相关产品推荐

