为spring boot微服务编写一个自动重启的脚本,并配置 Linux 的 crontab 以每 10 分钟检测一次,没有则重启,并计算上一次启动时间距离到现在的重启时间间隔。
以mtcsDatagovernanceBlood服务为例
vim mtcsDatagovernanceBlood_if_down_restart.sh
#!/bin/sh
#------- config -------
servicePath=/data01/mtcs/service/datagovernance-service/mtcsDatagovernanceBlood
service_name=mtcsDatagovernanceBlood
serviceJar=datagovernance-blood-server-*.jar
restartLogPath=/data01/mtcs/service/if_down/restart_logs
#------- restart -------
cd ${servicePath}
servicePid=$(ps -ef | grep ${serviceJar} | grep -v grep | awk '{print $2}')
echo $servicePid
# 确保日志目录存在
mkdir -p "$restartLogPath"
# 进程启动情况下,记录输出到log
if [ -n "$servicePid" ]; then
pid_stat=$(cat /proc/$servicePid/stat 2>/dev/null)
if [ -n "$pid_stat" ]; then
# 解析进程的启动时钟周期数(stat文件的第22个字段)
starttime=$(echo "$pid_stat" | awk '{print $22}')
# 读取系统启动时的时钟周期数
btime=$(cat /proc/stat | awk '/^btime /{print $2}')
# 获取系统的时钟频率
HZ=$(getconf CLK_TCK)
# 计算进程的启动时间的Unix时间戳
starttime_unix=$(( ($starttime / $HZ) + $btime ))
# 转换为可读日期时间格式
pid_start_time=$(date -d "@$starttime_unix" +"%Y-%m-%d %H:%M:%S")
echo "$(date '+%Y-%m-%d %H:%M:%S') The ${service_name} 服务处于存活状态, 进程ID = ${servicePid}, 启动时间 = ${pid_start_time}" >> "${restartLogPath}/${service_name}_restart.log"
echo ${pid_start_time}>${restartLogPath}/${service_name}_pid_start_time.txt
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法读取${service_name}的进程状态信息,进程ID = ${servicePid}" >> "${restartLogPath}/${service_name}_restart.log"
fi
else
# 进程未启动情况下,启动服务并记录日志
echo "$(date '+%Y-%m-%d %H:%M:%S') The ${service_name} 服务处于进程异常状态,并进行重启......" >> "${restartLogPath}/${service_name}_restart.log"
# 启动服务
sh "${servicePath}/bin/start.sh"
# 检查服务是否成功启动
sleep 2 # 等待一段时间确保服务有足够的时间启动
new_servicePid=$(ps -ef | grep ${serviceJar} | grep -v grep | awk '{print $2}')
if [ -n "$new_servicePid" ]; then
new_pid_stat=$(cat /proc/$new_servicePid/stat 2>/dev/null)
if [ -n "$new_pid_stat" ]; then
# 解析进程的启动时钟周期数(stat文件的第22个字段)
starttime=$(echo "$new_pid_stat" | awk '{print $22}')
# 读取系统启动时的时钟周期数
btime=$(cat /proc/stat | awk '/^btime /{print $2}')
# 获取系统的时钟频率
HZ=$(getconf CLK_TCK)
# 计算进程的启动时间的Unix时间戳
starttime_unix=$(( ($starttime / $HZ) + $btime ))
# 转换为可读日期时间格式
new_pid_start_time=$(date -d "@$starttime_unix" +"%Y-%m-%d %H:%M:%S")
#上一次的启动时间
modification_time=`cat ${restartLogPath}/${service_name}_pid_start_time.txt`
# 将日期字符串转换为时间戳(秒为单位)
modification_seconds=$(date -d "$modification_time" '+%s')
current_seconds=$(date -d "$new_pid_start_time" '+%s')
# 计算时间间隔(秒)
interval_seconds=$((current_seconds - modification_seconds))
# 将时间间隔转换为小数分钟
interval_minutes=$((interval_seconds / 60))
seconds_remainder=$((interval_seconds % 60))
minutes_decimal=$(echo "scale=2; $seconds_remainder / 60" | bc)
interval_minutes_decimal=$interval_minutes$minutes_decimal
echo "$(date '+%Y-%m-%d %H:%M:%S') ${service_name} 启动成功,新的进程ID = ${new_servicePid},重启时间 = ${new_pid_start_time},距离上次服务重启间隔分钟数 = ${interval_minutes_decimal},间隔秒数 = ${interval_seconds}" >> "${restartLogPath}/${service_name}_restart.log"
echo ${new_pid_start_time}>${restartLogPath}/${service_name}_pid_start_time.txt
echo "${service_name} 启动成功"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 无法读取${service_name}的进程状态信息,进程ID = ${new_servicePid}" >> "${restartLogPath}/${service_name}_restart.log"
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ${service_name} 启动失败,请检查原因!" >> "${restartLogPath}/${service_name}_restart.log"
fi
fi
需要将 servicePath、 service_name、restartLogPath等配置替换为微服务的实际环境配置
配置成定时任务
crontab -e
*/10 * * * * /bin/sh /data01/mtcs/service/if_down/mtcsDatagovernanceBlood_if_down_restart.sh
测试日志如下: