如何通过shell脚本监测nohup.out异常自动重启对应Java Jar进程
原有脚本问题排查
- 变量引用错误:定义的异常关键词变量是
STOPPED_MESSAGE,但grep判断时错误使用了不存在的$STOPPED,导致异常匹配逻辑完全失效 - 语法错误:
if [ $processId -eq ...]中]前缺少空格,会触发shell语法报错 - 进程匹配逻辑缺陷:如果没有匹配到
dataAdapter进程,processId为空,数值判断会直接报错;如果同时存在多个匹配进程,processId会拼接多个PID,无法正常执行判断和kill操作 - 工作目录缺失:脚本未切换到
SERVICE_PATH目录,crontab执行时默认工作目录是执行用户的家目录,会找不到dataAdapter.jar包 - 无效操作:给日志文件
nohup.out加执行权限完全没必要,属于冗余操作 - 异常匹配规则不合理:
grep -Fxq是精确匹配整行,而异常栈一般是多行输出,UnknownHostException只会是某一行的部分内容,匹配规则会失效 - 进程操作逻辑不合理:直接使用
kill -9强制杀进程,可能导致jar包业务数据丢失;杀进程后未确认进程已退出就删除日志、启动新进程,会出现旧进程仍占用日志文件、新进程启动失败等问题 - 环境变量缺失:crontab执行时不会加载用户的全量环境变量,可能出现找不到
java命令的问题
最优实现方案
优化后完整脚本
#!/bin/bash # 配置参数 SERVICE_PATH=/app/application/DataAdapter STOPPED_MESSAGE="java.net.UnknownHostException" LOG_FILE=${SERVICE_PATH}/nohup.out JAR_NAME=dataAdapter.jar # 配置java绝对路径,避免crontab找不到命令,可通过which java查看实际路径替换 JAVA_PATH=/usr/bin/java # 切换到工作目录 cd ${SERVICE_PATH} || exit 1 # 安全获取进程PID,只匹配jar包启动的进程,避免误杀 processId=$(pgrep -f "${JAR_NAME}") # 第一步:判断进程是否存在 if [[ -n "${processId}" ]]; then # 进程存在,检查日志是否包含指定异常 if grep -Fq "${STOPPED_MESSAGE}" "${LOG_FILE}"; then # 匹配到异常,先正常杀进程,等3秒没杀死再强制杀 kill ${processId} sleep 3 if pgrep -f "${JAR_NAME}" > /dev/null; then kill -9 ${processId} fi # 删除旧日志 rm -f ${LOG_FILE} # 后台启动新进程 nohup ${JAVA_PATH} -jar ${JAR_NAME} > ${LOG_FILE} 2>&1 & echo "检测到异常,已重启服务,新PID: $!" else echo "服务运行正常,无匹配异常,当前PID: ${processId}" fi else # 进程不存在,直接启动 rm -f ${LOG_FILE} nohup ${JAVA_PATH} -jar ${JAR_NAME} > ${LOG_FILE} 2>&1 & echo "检测到服务未运行,已启动,新PID: $!" fi echo "任务执行完成"
脚本优化说明
- 用
pgrep -f匹配jar包启动的进程,比ps+grep更精准,避免误杀其他含dataAdapter关键字的进程 - 增加工作目录切换,确保jar包和日志路径正确
- 提前配置java绝对路径,避免crontab环境变量问题
- 调整异常匹配逻辑,去掉精确整行匹配的
-x参数,只要行内包含异常关键词就命中 - 优化进程杀死逻辑,先发普通kill信号让进程优雅退出,超时再强制kill
- 增加进程不存在的兜底启动逻辑,实现服务异常宕机也能自动拉起
- 所有变量用花括号包裹,避免字符串拼接歧义
crontab配置说明
- 先给脚本加执行权限:
chmod +x /path/to/autoRestart.sh - 编辑crontab:执行
crontab -e,添加如下配置(示例是每1分钟执行一次,可根据需求调整间隔):
*/1 * * * * /path/to/autoRestart.sh >> /app/application/DataAdapter/restart.log 2>&1
- 配置说明:将脚本执行的日志输出到restart.log,方便排查定时任务执行问题,不要留空输出避免产生系统垃圾邮件
内容的提问来源于stack exchange,提问作者Tarik
相关产品推荐
相关产品推荐

