1. 告警切换脚本的应用场景与核心需求
在智慧园区运维场景中,监控告警的及时性和可靠性直接影响故障响应速度。传统告警系统往往存在以下痛点:
- 通知渠道单一:仅支持企业微信或钉钉其中一种,当某个平台出现服务波动时告警无法触达
- 静默管理缺失:夜间或维护时段仍需接收非紧急告警,造成信息干扰
- 恢复通知遗漏:故障恢复后缺乏自动确认机制,运维人员需手动检查状态
我们设计的脚本通过FFmpeg的流分析能力结合Shell脚本控制逻辑,实现:
- 双通道热切换:根据HTTP状态码自动在企微/钉钉机器人间切换
- 智能静默策略:基于时间戳的告警抑制,支持工作日/节假日差异化配置
- 状态闭环管理:通过FFmpeg的流检测结果触发恢复通知,形成告警-恢复闭环
关键设计原则:所有切换动作记录审计日志,确保可追溯性;静默期不阻断P0级告警
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与依赖配置
2.1 FFmpeg的定制化编译安装
告警检测核心需要FFmpeg支持RTSP流分析和状态检测功能:
bash复制# 安装依赖库
sudo apt-get install -y libavdevice-dev libavfilter-dev libopus-dev
# 源码编译(关键配置)
./configure \
--enable-libopus \
--enable-filter=drawtext \
--enable-libfreetype \
--extra-cflags=-I/usr/include/freetype2
make -j$(nproc) && sudo make install
验证安装效果:
bash复制ffmpeg -v quiet -stats -i rtsp://your_stream -f null - 2>&1 | grep -q "Video:" && echo "Stream OK"
2.2 消息平台接入准备
企业微信机器人配置
- 进入目标群聊 → 右上角菜单 → 添加群机器人
- 记录Webhook地址(格式:
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx) - 设置自定义关键词为"告警","恢复"
钉钉机器人安全设置
- 群设置 → 智能群助手 → 添加机器人
- 选择"自定义"类型
- 开启加签验证(记录timestamp和sign)
- IP白名单添加监控服务器地址
3. 核心脚本逻辑实现
3.1 告警路由切换模块
bash复制#!/bin/bash
# 参数:$1=告警级别 $2=告警内容 $3=静默标志
WECHAT_WEBHOOK="企业微信webhook"
DINGTALK_WEBHOOK="钉钉webhook"
DINGTALK_SECRET="加签密钥"
# 通道状态检测函数
check_channel() {
local url=$1
http_code=$(curl -o /dev/null -s -w %{http_code} "$url")
[ $http_code -eq 200 ] && return 0 || return 1
}
# 消息路由选择逻辑
if [[ $3 == "silent" && $1 != "P0" ]]; then
echo "$(date) [SILENT] $2" >> /var/log/alert_silent.log
else
if check_channel $WECHAT_WEBHOOK; then
send_to_wechat "$1" "$2"
else
timestamp=$(date +%s%3N)
sign=$(echo -ne "$timestamp\n$DINGTALK_SECRET" | openssl dgst -sha256 -binary | base64)
send_to_dingtalk "$1" "$2" $timestamp $sign
fi
fi
3.2 静默周期时间策略
采用crontab管理静默时段,工作日22:00-次日8:00静默非P0告警:
bash复制# /etc/crontab 配置示例
0 22 * * 1-5 root /usr/local/bin/alert_ctl.sh enable_silent
0 8 * * 1-5 root /usr/local/bin/alert_ctl.sh disable_silent
# 节假日特殊处理(需提前维护holiday.list文件)
0 0 1 1 * root if grep -q $(date +%Y%m%d) /etc/holiday.list; then /usr/local/bin/alert_ctl.sh enable_silent; fi
3.3 恢复通知触发机制
通过FFmpeg持续检测流状态变化:
bash复制#!/bin/bash
# 流状态检测脚本
while true; do
stream_state=$(ffmpeg -v error -i rtsp://cam1 -f null - 2>&1)
if [[ $stream_state != *"Connection refused"* ]]; then
if [[ -f "/tmp/stream_down_flag" ]]; then
send_restore_notice "摄像头1 视频流已恢复"
rm -f /tmp/stream_down_flag
fi
else
touch /tmp/stream_down_flag
fi
sleep 30
done
4. 生产环境部署要点
4.1 高可用架构设计
建议采用双节点部署模式:
code复制 +-----------------+
| 负载均衡层 |
| (Nginx/HAProxy) |
+-------+---------+
|
+---------------+---------------+
| |
+-------+-------+ +-------+-------+
| 主控节点 | | 备用节点 |
| (运行主脚本) |<----心跳----->| (热备状态) |
+---------------+ +---------------+
关键配置参数:
nginx复制# Nginx负载均衡配置示例
upstream alert_servers {
server 192.168.1.10:8000 weight=5;
server 192.168.1.11:8000 backup;
keepalive 32;
}
4.2 日志审计与监控
日志规范建议:
- /var/log/alert_send.log:记录所有消息发送记录
- /var/log/alert_switch.log:通道切换事件
- /var/log/alert_error.log:异常错误信息
使用logrotate进行日志管理:
conf复制/var/log/alert_*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
5. 常见问题排查指南
5.1 消息发送失败排查流程
mermaid复制graph TD
A[发送失败] --> B{检查网络连通性}
B -->|不通| C[检查防火墙/路由]
B -->|通| D{验证Webhook地址}
D -->|无效| E[重新获取机器人token]
D -->|有效| F{检查API返回}
F -->|403| G[验证加签/timestamp]
F -->|429| H[降低发送频率]
5.2 FFmpeg检测异常处理
典型错误及解决方案:
-
"Connection refused"
- 检查摄像头电源和网络
- 验证RTSP端口是否改变(默认554)
-
"Invalid data found"
bash复制# 增加分析缓冲区(单位:字节) ffmpeg -analyzeduration 1000000 -i rtsp://cam1 -f null - -
"Unexpected EOF"
- 调整TCP传输参数:
bash复制
ffmpeg -rtsp_transport tcp -max_delay 500000 -i rtsp://cam1
6. 进阶优化方向
6.1 智能路由权重算法
根据历史成功率动态调整通道优先级:
python复制# 伪代码示例
def calculate_weight(platform):
success_rate = get_7day_success_rate(platform)
response_time = get_avg_response_time(platform)
return success_rate * 0.7 + (1 - response_time/5000) * 0.3
6.2 视频指纹比对验证
使用FFmpeg生成视频指纹辅助故障诊断:
bash复制# 生成基准指纹
ffmpeg -i rtsp://cam1 -vf fps=1,scale=320:-1 -pix_fmt gray -frames 1 -f md5 -
# 实时比对
current_fp=$(ffmpeg -i rtsp://cam1 -vf fps=1...)
if [ "$current_fp" != "$baseline_fp" ]; then
send_alert "视频指纹异常"
fi
实际部署中发现,企业微信在跨地域传输时容易出现消息延迟。我们的解决方案是在华东、华北各部署一套接入网关,通过DNS解析分流。具体实现是在发送前检测接收方IP地域:
bash复制# 地域检测函数示例
get_region() {
geoip=$(curl -s http://ip-api.com/json/$1)
echo $geoip | jq -r '.regionName'
}
if [ $(get_region $target_ip) == "华东" ]; then
use_east_gateway
fi
