题目
设计高并发服务监控与自愈Shell脚本
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
并发控制,服务状态监控,错误处理,远程命令执行,资源管理
快速回答
实现一个可监控多台服务器关键服务状态并自动恢复的Shell脚本,需包含:
- 使用SSH密钥对实现免密远程执行
- 通过
systemctl is-active检查服务状态 - 用GNU Parallel实现并发控制
- 失败服务自动重启并记录审计日志
- 添加超时机制防止进程阻塞
- 资源限制避免过载
核心需求
设计一个能在生产环境中监控数百台服务器的关键服务(如Nginx/MySQL),当服务异常时自动恢复并生成审计报告的脚本,需解决:
- 高并发执行时的资源竞争
- 网络波动导致的假阳性判断
- 自愈操作的幂等性
- 详尽的错误分类处理
代码实现示例
#!/bin/bash
# 配置区域
SERVERS=("web1.example.com" "db2.example.com" "cache3.example.com")
SERVICES=("nginx" "mysql" "redis")
MAX_CONCURRENT=50
TIMEOUT=10
LOG_FILE="/var/log/service_monitor_$(date +%Y%m%d).log"
# 审计日志函数
log_audit() {
echo "[$(date '+%F %T')] $1" | tee -a "$LOG_FILE"
}
# 服务检查函数
check_service() {
local server="$1"
local service="$2"
# 带超时的SSH执行
ssh -o ConnectTimeout=$TIMEOUT -o BatchMode=yes "$server" \
"systemctl is-active '$service' >/dev/null 2>&1" \
&& return 0 || return 1
}
# 服务恢复函数
recover_service() {
local server="$1"
local service="$2"
ssh -o BatchMode=yes "$server" "systemctl restart '$service'" && \
log_audit "SUCCESS: $server $service recovered" || \
log_audit "CRITICAL: $server $service recovery failed"
}
# 主监控流程
export -f check_service recover_service log_audit
for server in "${SERVERS[@]}"; do
for service in "${SERVICES[@]}"; do
echo "$server $service"
done
done | parallel -j $MAX_CONCURRENT --colsep ' ' '
if ! check_service {1} {2}; then
log_audit "WARN: {1} {2} is down"
recover_service {1} {2}
fi
'
# 生成摘要报告
awk '/CRITICAL|WARN|SUCCESS/ {print}' "$LOG_FILE" > "/tmp/service_report_$(date +%H%M).txt"关键技术点
- 并发控制:使用GNU Parallel管理并发进程(-j参数),避免fork炸弹
- 超时处理:SSH的ConnectTimeout参数防止僵尸进程
- 错误分类:
- 连接超时:跳过不阻塞后续任务
- 服务停止:触发重启流程
- 重启失败:标记为CRITICAL级别
- 幂等设计:重启命令可重复执行不影响系统状态
最佳实践
- 安全加固:
- 使用SSH证书代替密码
- 限制sudo权限到特定命令
- 设置单独的监控账户
- 资源管理:
- 通过ulimit限制子进程数
- 监控脚本自身CPU/MEM使用
- 日志规范:
- 结构化日志(时间/主机/服务/状态)
- 日志轮转防止磁盘写满
常见陷阱
- 网络抖动误判:增加重试机制(示例未展示,可添加ping检测)
- 并发过高:根据目标服务器性能动态调整MAX_CONCURRENT
- 命令注入风险:始终用引号包裹变量(如'systemctl restart "$service"')
- 僵尸进程累积:添加trap 'kill $(jobs -p)' EXIT清理子进程
扩展优化
- 告警集成:在CRITICAL日志后追加curl调用告警API
- 性能基线:增加响应时间监控(如
time systemctl status) - 自愈策略扩展:
- 重启失败后触发故障转移
- 连续失败N次停止恢复避免雪崩
- 配置解耦:将服务器/服务列表移至外部配置文件