本文目录导读:

我来详细介绍Shell脚本实现看门狗定时器的几种方法:
基础看门狗实现
简单的循环检测看门狗
#!/bin/bash
# 看门狗脚本
WATCHDOG_INTERVAL=10 # 检测间隔(秒)
WATCHDOG_TIMEOUT=30 # 超时时间(秒)
LAST_HEARTBEAT_FILE="/tmp/watchdog_last_heartbeat"
LOG_FILE="/var/log/watchdog.log"
# 创建或更新心跳时间戳
function send_heartbeat() {
echo "$(date +%s)" > "$LAST_HEARTBEAT_FILE"
echo "[$(date)] 心跳已发送" >> "$LOG_FILE"
}
# 检查是否超时
function check_timeout() {
if [ ! -f "$LAST_HEARTBEAT_FILE" ]; then
return 1 # 没有心跳文件,视为超时
fi
current_time=$(date +%s)
last_time=$(cat "$LAST_HEARTBEAT_FILE")
time_diff=$((current_time - last_time))
if [ $time_diff -gt $WATCHDOG_TIMEOUT ]; then
return 1 # 超时
fi
return 0 # 正常
}
# 看门狗主循环
function watchdog_main() {
echo "[$(date)] 看门狗服务启动" >> "$LOG_FILE"
echo "[$(date)] 检测间隔: ${WATCHDOG_INTERVAL}s, 超时时间: ${WATCHDOG_TIMEOUT}s" >> "$LOG_FILE"
while true; do
if ! check_timeout; then
echo "[$(date)] 警告: 检测到超时!执行恢复操作..." >> "$LOG_FILE"
# 执行恢复操作,比如重启服务
systemctl restart your_service 2>/dev/null || \
/etc/init.d/your_service restart 2>/dev/null
# 发送通知
send_alert_email "服务已超时,已自动重启"
fi
sleep $WATCHDOG_INTERVAL
done
}
# 发送警报邮件函数
function send_alert_email() {
local message="$1"
echo "看门狗警报: $message" | mail -s "[看门狗] 服务异常" admin@example.com
}
# 启动看门狗
watchdog_main
监控特定进程的看门狗
#!/bin/bash
# 进程监控看门狗
MONITOR_PROCESS="your_service_name" # 要监控的进程名
PROCESS_CHECK_INTERVAL=5 # 检测间隔
MAX_RESTART_ATTEMPTS=3 # 最大重启次数
RESTART_WINDOW=60 # 重启计数窗口(秒)
RESTART_COUNT=0
FIRST_RESTART_TIME=0
# 检查进程是否运行
function is_process_running() {
pgrep -x "$MONITOR_PROCESS" > /dev/null 2>&1
}
# 重启进程
function restart_process() {
echo "[$(date)] 正在重启进程: $MONITOR_PROCESS"
# 尝试优雅停止
pkill -SIGTERM "$MONITOR_PROCESS" 2>/dev/null
sleep 2
# 强制杀掉
pkill -SIGKILL "$MONITOR_PROCESS" 2>/dev/null
sleep 1
# 启动进程
systemctl start "$MONITOR_PROCESS" 2>/dev/null || \
/etc/init.d/"$MONITOR_PROCESS" start 2>/dev/null
return $?
}
# 重置重启计数
function reset_restart_count() {
current_time=$(date +%s)
if [ $((current_time - FIRST_RESTART_TIME)) -gt $RESTART_WINDOW ]; then
RESTART_COUNT=0
FIRST_RESTART_TIME=0
fi
}
# 主监控循环
while true; do
if ! is_process_running; then
reset_restart_count
if [ $RESTART_COUNT -lt $MAX_RESTART_ATTEMPTS ]; then
((RESTART_COUNT++))
if [ $RESTART_COUNT -eq 1 ]; then
FIRST_RESTART_TIME=$(date +%s)
fi
echo "[$(date)] 进程未运行,尝试重启 (第${RESTART_COUNT}次)"
if restart_process; then
echo "[$(date)] 重启成功"
else
echo "[$(date)] 重启失败"
fi
else
echo "[$(date)] 错误: 已达到最大重启次数"
# 发送紧急通知
send_alert_escalation "$MONITOR_PROCESS"
fi
fi
sleep $PROCESS_CHECK_INTERVAL
done
超时监控看门狗
#!/bin/bash
# 超时监控看门狗 - 监控某个命令的执行时间
TIMEOUT=60 # 超时时间(秒)
CMD_TO_MONITOR="your_long_running_command"
STATUS_FILE="/tmp/wdt_status"
# 监控命令执行
function monitor_command() {
local start_time=$(date +%s)
local timeout=$1
local cmd="$2"
# 在后台执行命令
eval "$cmd" &
local cmd_pid=$!
# 等待命令完成或超时
while kill -0 $cmd_pid 2>/dev/null; do
current_time=$(date +%s)
elapsed=$((current_time - start_time))
if [ $elapsed -gt $timeout ]; then
echo "[$(date)] 命令执行超时,强制终止 PID: $cmd_pid"
kill -9 $cmd_pid 2>/dev/null
return 1
fi
sleep 1
done
wait $cmd_pid
return $?
}
# 示例:监控数据库查询
function monitor_db_query() {
local query="SELECT COUNT(*) FROM large_table;"
local timeout=30
echo "[$(date)] 开始监控数据库查询"
if ! monitor_command $timeout "mysql -e \"$query\""; then
echo "[$(date)] 数据库查询超时,记录日志"
# 记录到系统日志
logger -t watchdog "数据库查询超时"
fi
}
# 监控Web服务响应
function monitor_web_service() {
local url="http://localhost:8080/health"
local timeout=10
echo "[$(date)] 检查Web服务: $url"
if ! monitor_command $timeout "curl -s -o /dev/null -w '%{http_code}' $url"; then
echo "[$(date)] Web服务响应超时"
# 重启Web服务器
systemctl restart nginx 2>/dev/null
fi
}
# 主循环
while true; do
monitor_db_query
monitor_web_service
# 记录状态
echo "OK $(date +%s)" > "$STATUS_FILE"
sleep 30
done
使用定时任务的看门狗
#!/bin/bash
# 通过cron运行的看门狗检查脚本
# 将此脚本添加到crontab:*/5 * * * * /path/to/watchdog_cron.sh
CONFIG_FILE="/etc/watchdog.conf"
STATUS_FILE="/tmp/watchdog_status"
LOG_FILE="/var/log/watchdog.log"
# 发送心跳
function heartbeat() {
touch "$STATUS_FILE"
echo "$(date +%s)" > "$STATUS_FILE"
}
# 检查服务状态
function check_services() {
local services=("nginx" "mysql" "redis")
local failed_services=()
for service in "${services[@]}"; do
if ! systemctl is-active --quiet "$service" 2>/dev/null; then
failed_services+=("$service")
fi
done
if [ ${#failed_services[@]} -gt 0 ]; then
echo "[$(date)] 检测到服务异常: ${failed_services[*]}" >> "$LOG_FILE"
for service in "${failed_services[@]}"; do
systemctl restart "$service" 2>/dev/null
echo "[$(date)] 重启服务: $service" >> "$LOG_FILE"
fi
fi
}
# 检查系统资源
function check_system_resources() {
# CPU负载
load=$(uptime | awk -F'load average:' '{print $2}' | cut -d',' -f1 | tr -d ' ')
if (( $(echo "$load > 10" | bc -l) )); then
echo "[$(date)] CPU负载过高: $load" >> "$LOG_FILE"
# 执行清理或警报
fi
# 内存使用
memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
if (( $(echo "$memory_usage > 90" | bc -l) )); then
echo "[$(date)] 内存使用过高: ${memory_usage}%" >> "$LOG_FILE"
fi
# 磁盘使用
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$disk_usage" -gt 90 ]; then
echo "[$(date)] 磁盘使用过高: ${disk_usage}%" >> "$LOG_FILE"
# 清理日志或警报
fi
}
# 主函数
function main() {
heartbeat
check_services
check_system_resources
}
main
完整的看门狗系统
#!/bin/bash
# 完整的看门狗系统脚本
# 使用方法: ./watchdog.sh {start|stop|status|heartbeat}
# 配置
APP_NAME="myapp"
PID_FILE="/var/run/${APP_NAME}_watchdog.pid"
LOG_FILE="/var/log/${APP_NAME}_watchdog.log"
STATUS_FILE="/tmp/${APP_NAME}_status"
HEARTBEAT_INTERVAL=10
TIMEOUT=30
MAX_RESTARTS=3
RESTART_WINDOW=300
# 初始化变量
RESTART_COUNT=0
FIRST_RESTART=0
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 发送心跳
heartbeat() {
echo "ALIVE" > "$STATUS_FILE"
date +%s >> "$STATUS_FILE"
}
# 检查状态
check_status() {
if [ -f "$STATUS_FILE" ]; then
local timestamp=$(tail -1 "$STATUS_FILE" 2>/dev/null)
local current_time=$(date +%s)
if [ -n "$timestamp" ] && [ "$timestamp" -gt 0 ]; then
local elapsed=$((current_time - timestamp))
if [ "$elapsed" -le "$TIMEOUT" ]; then
return 0 # 正常
fi
fi
fi
return 1 # 超时
}
# 重启应用
restart_app() {
log "正在重启应用..."
# 停止应用
systemctl stop "$APP_NAME" 2>/dev/null
sleep 2
# 确保进程已停止
local pid=$(pgrep -x "$APP_NAME" 2>/dev/null)
if [ -n "$pid" ]; then
kill -9 "$pid" 2>/dev/null
sleep 1
fi
# 启动应用
systemctl start "$APP_NAME" 2>/dev/null
if [ $? -eq 0 ]; then
log "应用重启成功"
return 0
else
log "应用重启失败"
return 1
fi
}
# 启动看门狗
start_watchdog() {
if [ -f "$PID_FILE" ]; then
local old_pid=$(cat "$PID_FILE")
if kill -0 "$old_pid" 2>/dev/null; then
log "看门狗已在运行 (PID: $old_pid)"
exit 1
fi
fi
log "启动看门狗..."
# 启动看门狗主循环
(
log "看门狗已启动 (PID: $$)"
echo $$ > "$PID_FILE"
while true; do
if ! check_status; then
log "检测到超时!"
# 检查重启次数
local current_time=$(date +%s)
if [ $RESTART_COUNT -eq 0 ]; then
FIRST_RESTART=$current_time
fi
if [ $((current_time - FIRST_RESTART)) -gt $RESTART_WINDOW ]; then
RESTART_COUNT=0
fi
if [ $RESTART_COUNT -lt $MAX_RESTARTS ]; then
((RESTART_COUNT++))
restart_app
else
log "达到最大重启次数,等待人为干预"
# 发送警报
echo "应用 $APP_NAME 出现问题,请检查" | \
mail -s "[紧急] 应用异常" admin@example.com
fi
fi
sleep $HEARTBEAT_INTERVAL
done
) &
log "看门狗已启动"
}
# 停止看门狗
stop_watchdog() {
if [ -f "$PID_FILE" ]; then
local pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
kill "$pid"
log "看门狗已停止"
fi
rm -f "$PID_FILE"
fi
}
# 查看状态
status_watchdog() {
if [ -f "$PID_FILE" ]; then
local pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
echo "看门狗正在运行 (PID: $pid)"
if check_status; then
echo "应用状态: 正常"
else
echo "应用状态: 异常(超时)"
fi
else
echo "看门狗未运行(PID文件存在但进程不存在)"
rm -f "$PID_FILE"
fi
else
echo "看门狗未运行"
fi
}
# 主函数
case "${1:-help}" in
start)
start_watchdog
;;
stop)
stop_watchdog
;;
restart)
stop_watchdog
sleep 1
start_watchdog
;;
status)
status_watchdog
;;
heartbeat)
heartbeat
echo "心跳已发送"
;;
help|*)
echo "用法: $0 {start|stop|restart|status|heartbeat}"
echo ""
echo "Commands:"
echo " start 启动看门狗"
echo " stop 停止看门狗"
echo " restart 重启看门狗"
echo " status 查看看门狗状态"
echo " heartbeat 发送心跳信号"
exit 1
;;
esac
exit 0
应用端使用示例
#!/bin/bash
# 应用主程序
WATCHDOG_SCRIPT="/path/to/watchdog.sh"
HEARTBEAT_INTERVAL=5
# 发送心跳信号
function send_heartbeat() {
$WATCHDOG_SCRIPT heartbeat
}
# 主程序循环
function main() {
echo "应用启动..."
# 主业务逻辑
while true; do
# 执行实际工作
do_work
# 发送心跳
send_heartbeat
# 等待
sleep $HEARTBEAT_INTERVAL
done
}
main
使用方法
-
启动看门狗:
./watchdog.sh start
-
停止看门狗:
./watchdog.sh stop
-
查看状态:
./watchdog.sh status
-
发送心跳(应用调用):
./watchdog.sh heartbeat
这些脚本可以根据实际需求进行调整和扩展,选择合适的看门狗实现方式取决于你的具体应用场景和需求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播