定时检测spring boot微服务状态并重启(单个服务)

为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

测试日志如下:

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值