内网系统定时更新
内网系统定时更新
背景:由于目前项目架构不能支持不停机部署,为避免影响用户使用,需花费晚上的时间和精力去人工部署。
软件技术:
At 命令用于安排一次性任务。与 Cron 不同,At 适用于只需执行一次的任务。这些任务在指定的未来某个时间点执行。
- 特点:最适合于那些不需要重复执行的任务。
- 用法:使用 at 命令,后跟执行任务的具体时间。之后,输入要执行的命令,然后结束输入。
- 时间格式:At 允许多种时间格式,例如具体时间点或“现在之后”的时间表达方式。
实现简介:
通过At定时执行Shell命令的功能,在脚本中定义相关选项和逻辑。通过不同选项实现主要两种效果,一是定时重启多个容器,二是到时后据正在手术数量阈值判断是否更新不更新则等待五分钟后再次执行Shell脚本。
安装路径:
at
OpenEuler系统:https://search.oepkgs.net/zh-CN
其他操作系统:https://pkgs.org/
使用细则
- 配置相关属性
- 确认LOG_FILE的目录是存在的
- 修改请求后端手术的手术数量正确
- 将其至于/usr/local/bin/下,并授予可执行权限
# 授予可执行权限
chmod +x restart_task.sh
# 移动文件至/usr/local/bin/下
mv restart_task.sh /usr/local/bin/
3.
restart_task.sh
restart_task.sh -t 22:00 -s utellicare-backend -s utellicare-web -a
选项释义
-t 指定执行时间 默认晚上22:00
-s 指定重启服务 必须项
-a 执行询问等待,若不提供则到时直接更新
-n 指定询问可更新的正在手术数量阈值 默认5
相关命令
#查看待执行定时任务
atq
#查看任务具体信息,taskId从atq命令可得到
at -c taskId
#删除定时任务
atrm taskId
附
#!/bin/bash
# 设置默认时间为今晚十点
DEFAULT_TIME="22:00"
DEFAULT_THRESHOLD=5 # 默认阈值
URL=""
# 日志文件
LOG_FILE="/home/uvi/app-deploy/at_docker_service_restart.log"
# 正在请求关键数量数量请求
BASE_URL="http://172.17.0.1:9080/xxx
# 解析命令行参数
SERVICES=() # 初始化服务名称数组
while getopts ":t:s:an:r" opt; do
case $opt in
t)
TIME="$OPTARG"
;;
s)
# 捕获所有 -s 参数
SERVICES+=("$OPTARG")
;;
a)
CHECK_API=true
;;
n)
THRESHOLD="$OPTARG"
;;
r)
IS_SCHEDULED_RUN=true
;;
\?)
echo "无效选项: -$OPTARG" >&2
exit 1
;;
:)
echo "选项 -$OPTARG 需要参数." >&2
exit 1
;;
esac
done
# 检查 -s 选项是否提供
if [ ${#SERVICES[@]} -eq 0 ]; then
echo "错误: -s 选项是必传值,请指定要重启的服务。"
exit 1
fi
# 如果没有提供时间,使用默认值
TIME=${TIME:-$DEFAULT_TIME}
# 如果没有提供阈值,使用默认值
THRESHOLD=${THRESHOLD:-$DEFAULT_THRESHOLD}
# 检查数据并执行重启
check_and_restart() {
CURRENT_TIME=$(date '+%Y-%m-%d %H:%M')
echo "$CURRENT_TIME 开始检查数据..." >> "$LOG_FILE"
# 构造 URL
URL="$BASE_URL&surgeryTime_start=$CURRENT_TIME&surgeryTime_end=$CURRENT_TIME"
ENCODED_URL=$(echo "$URL" | sed 's/ /%20/g')
echo "$CURRENT_TIME 请求的 URL: $ENCODED_URL" >> "$LOG_FILE"
# 发送请求并解析数据
response=$(curl "$ENCODED_URL")
echo "$response" >> "$LOG_FILE"
data=$(echo "$response" | sed -n 's/.*"data":\s*\([0-9]*\).*/\1/p')
echo "$data" >> "$LOG_FILE"
if [ -z "$data" ]; then
echo "$CURRENT_TIME 错误: 无法解析响应数据。" >> "$LOG_FILE"
return 1
fi
echo "$CURRENT_TIME 当前数据: $data" >> "$LOG_FILE"
if [ "$data" -lt "$THRESHOLD" ]; then
# 数据小于阈值,执行重启
echo "$CURRENT_TIME 数据小于阈值,执行重启: docker restart ${SERVICES[*]}" >> "$LOG_FILE"
docker restart "${SERVICES[@]}" >> "$LOG_FILE" 2>&1
else
# 数据大于等于阈值,设置 5 分钟后的定时任务
echo "$CURRENT_TIME 数据大于等于阈值,等待 5 分钟后重试..." >> "$LOG_FILE"
# 构造 at 任务命令
at_command="bash $0 -t \"now + 5 minutes\""
for service in "${SERVICES[@]}"; do
at_command+=" -s \"$service\""
done
at_command+=" -a -n \"$THRESHOLD\" -r"
echo "$at_command" | at now + 5 minutes
fi
}
# 如果是指定定时任务触发的运行,则执行 check_and_restart
if [ "$IS_SCHEDULED_RUN" = true ]; then
echo "执行直接请求模式,若符合阈值则直接重启"
check_and_restart
exit 0
fi
# 使用 at 命令设置定时任务
if [ "$CHECK_API" = true ]; then
# 如果指定了 -a 选项,执行检查逻辑
# 构造 at 任务命令
at_command="bash $0 -t \"$TIME\""
for service in "${SERVICES[@]}"; do
at_command+=" -s \"$service\""
done
at_command+=" -a -n \"$THRESHOLD\" -r"
echo "$at_command" | at "$TIME"
else
# 如果没有指定 -a 选项,直接执行重启命令
echo "
CURRENT_TIME=\$(date '+%Y-%m-%d %H:%M')
echo \"\$CURRENT_TIME docker restart ${SERVICES[*]}\" >> \"$LOG_FILE\" 2>&1
docker restart ${SERVICES[*]} >> \"$LOG_FILE\" 2>&1
" | at "$TIME"
fi
# 检查 at 命令是否成功
if [ $? -eq 0 ]; then
if [ "$CHECK_API" = true ]; then
echo "任务已设置,将在今晚 $TIME 执行检查,直到数据小于 $THRESHOLD 后重启服务。"
else
echo "任务已设置,将在今晚 $TIME 执行: docker restart ${SERVICES[*]}"
fi
else
echo "错误: 无法设置任务。请检查时间和服务的格式是否正确。"
exit 1
fi

浙公网安备 33010602011771号