本文目录导读:

在Shell脚本中监控系统时间同步,有多种方法可以实现,以下是几种常用的监控方案:
使用 timedatectl 命令
#!/bin/bash
# 监控系统时间同步状态
check_time_sync() {
# 获取时间同步状态
sync_status=$(timedatectl status | grep "System clock synchronized" | awk '{print $4}')
if [ "$sync_status" == "yes" ]; then
echo "[OK] 系统时间已同步"
# 获取当前NTP服务器信息
ntp_servers=$(timedatectl show-timesync --property=ServerName= --value)
echo "[INFO] 当前NTP服务器: $ntp_servers"
return 0
else
echo "[ERROR] 系统时间未同步"
# 尝试重启时间同步服务
systemctl restart systemd-timesyncd
return 1
fi
}
# 主循环
while true; do
check_time_sync
sleep 60 # 每60秒检查一次
done
使用 ntpq 命令 (NTP客户端)
#!/bin/bash
# 监控NTP同步状态
check_ntp_sync() {
# 检查ntp服务是否运行
if ! systemctl is-active ntp > /dev/null 2>&1; then
echo "[ERROR] NTP服务未运行"
return 1
fi
# 获取NTP同步状态
ntp_output=$(ntpq -pn 2>/dev/null)
# 检查是否有同步的服务器
if echo "$ntp_output" | grep -q '^\*'; then
current_server=$(echo "$ntp_output" | grep '^\*' | awk '{print $2}')
offset=$(ntpq -c "rv 0 offset" | awk -F'=' '{print $2}')
echo "[OK] NTP已同步"
echo "[INFO] 当前NTP服务器: $current_server"
echo "[INFO] 时间偏移: ${offset}ms"
# 检查时间偏移是否过大(超过100ms)
if [ "$(echo "$offset > 100" | bc -l)" -eq 1 ]; then
echo "[WARN] 时间偏移过大: ${offset}ms"
return 1
fi
else
echo "[ERROR] 未同步到任何NTP服务器"
return 1
fi
}
# 主循环
while true; do
check_ntp_sync
sleep 300 # 每5分钟检查一次
done
使用 chronyc 命令 (Chrony客户端)
#!/bin/bash
# 监控Chrony时间同步
check_chrony_sync() {
# 检查chrony服务状态
if ! systemctl is-active chronyd > /dev/null 2>&1; then
echo "[ERROR] Chrony服务未运行"
return 1
fi
# 获取同步状态
chrony_output=$(chronyc tracking 2>/dev/null)
if [ $? -eq 0 ]; then
# 提取关键信息
sync_status=$(echo "$chrony_output" | grep "Leap status" | awk -F':' '{print $2}')
offset=$(echo "$chrony_output" | grep "Last offset" | awk -F':' '{print $2}')
if [ "$(echo "$sync_status" | grep -i "normal" | wc -l)" -gt 0 ]; then
echo "[OK] Chrony时间同步正常"
echo "[INFO] 时间偏移: $offset"
# 获取NTP源信息
ntp_sources=$(chronyc sources -v 2>/dev/null)
echo "[INFO] NTP源信息:"
echo "$ntp_sources"
else
echo "[ERROR] Chrony同步异常"
return 1
fi
else
echo "[ERROR] 无法获取Chrony状态"
return 1
fi
}
# 主循环
while true; do
check_chrony_sync
sleep 300 # 每5分钟检查一次
done
综合监控脚本
#!/bin/bash
# 配置文件
LOG_FILE="/var/log/time_sync_monitor.log"
ALERT_EMAIL="admin@example.com"
OFFSET_THRESHOLD=100 # ms
# 日志函数
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 发送告警
send_alert() {
local message="$1"
echo "$message" | mail -s "时间同步告警" "$ALERT_EMAIL"
log_message "已发送告警: $message"
}
# 同步时间
sync_time() {
log_message "尝试同步时间..."
# 尝试使用chrony同步
if command -v chronyc &>/dev/null; then
chronyc -a makestep &>/dev/null
if [ $? -eq 0 ]; then
log_message "Chrony时间同步成功"
return 0
fi
fi
# 尝试使用ntpdate同步
if command -v ntpdate &>/dev/null; then
ntpdate -u ntp.aliyun.com &>/dev/null
if [ $? -eq 0 ]; then
log_message "ntpdate时间同步成功"
return 0
fi
fi
log_message "时间同步失败"
return 1
}
# 主监控函数
monitor_time_sync() {
log_message "开始监控时间同步..."
while true; do
local sync_status=""
local offset=0
# 检查系统时间同步状态
if command -v timedatectl &>/dev/null; then
sync_status=$(timedatectl status | grep "System clock synchronized" | awk '{print $4}')
if [ "$sync_status" == "yes" ]; then
log_message "系统时间已同步"
else
log_message "系统时间未同步"
# 尝试同步时间
sync_time
# 发送告警
send_alert "系统时间同步异常,已尝试恢复"
fi
fi
# 检查NTP同步状态
if command -v ntpq &>/dev/null; then
offset=$(ntpq -c "rv 0 offset" 2>/dev/null | awk -F'=' '{print $2}')
if [ -n "$offset" ]; then
offset_ms=${offset%.*}
if [ "$offset_ms" -gt "$OFFSET_THRESHOLD" ] || [ "$offset_ms" -lt "-$OFFSET_THRESHOLD" ]; then
log_message "时间偏移过大: ${offset}ms"
send_alert "时间偏移超过阈值: ${offset}ms"
fi
fi
fi
# 每60秒检查一次
sleep 60
done
}
# 启动监控
monitor_time_sync
轻量级监控方案 (使用系统调用)
#!/bin/bash
# 使用系统时间偏移检测
check_offset() {
# 获取两次系统调用之间的时间差
start=$(date +%s%N)
sleep 0.1
end=$(date +%s%N)
# 计算实际经过时间
elapsed=$((end - start))
# 检查时间是否倒流
if [ "$elapsed" -lt 0 ]; then
echo "[ERROR] 检测到时间倒退: ${elapsed}ns"
return 1
fi
# 检查时间是否异常
expected=100000000 # 100ms in ns
diff=$((elapsed - expected))
diff_ms=$((diff / 1000000))
echo "[INFO] 时间精度: ${diff_ms}ms"
if [ "${diff_ms#-}" -gt 10 ]; then
echo "[WARN] 时间偏移异常: ${diff_ms}ms"
return 1
fi
return 0
}
# 主循环
while true; do
check_offset
sleep 60
done
使用方法
-
选择合适的方法:
timedatectl:适用于systemd系统ntpq:传统NTP客户端chronyc:现代chrony客户端
-
设置监控频率:
- 生产环境:每5-15分钟
- 关键系统:每1-5分钟
-
配置告警:
- 邮件通知
- 系统日志
- 短信/微信通知
-
自动修复:
- 重启服务
- 手动同步
- 切换备用NTP服务器
建议
-
使用NTP服务的最佳实践:
# 配置NTP源 echo "server ntp.aliyun.com iburst" > /etc/ntp.conf echo "server ntp.tencent.com iburst" >> /etc/ntp.conf # 启动服务 systemctl enable ntpd systemctl start ntpd
-
对于高精度要求的环境,建议使用chrony:
# 安装chrony yum install chrony # CentOS/RHEL apt install chrony # Ubuntu/Debian # 配置 echo "pool ntp.aliyun.com iburst" > /etc/chrony.conf # 启动 systemctl enable chronyd systemctl start chronyd
根据你的具体需求(精度要求、系统类型、可用工具等)选择合适的监控方案。