从零构建高效运维体系
目录导读
- 监控网站可用性的核心意义
- 主流监控方案对比与选型
- 基于Shell脚本的简易监控(含代码)
- 使用Python实现进阶监控脚本
- 集成报警通知:邮件、短信与钉钉
- 脚本优化:并发检测与日志轮转
- 常见问题与问答(Q&A)
- 总结与最佳实践建议
监控网站可用性的核心意义
在数字化时代,网站可用性直接关系到企业营收与用户信任,根据行业统计,每1秒的加载延迟可能导致7%的转化率流失,而一次长达10分钟的宕机可能造成数十万的直接损失,编写监控脚本的目的在于:

- 实时感知故障:在用户投诉前发现异常
- 量化服务等级:记录响应时间与可用率,满足SLA(服务等级协议)要求
- 辅助根因分析:通过历史数据定位性能瓶颈
关键指标:可用率(Uptime)应达到99.9%以上,响应时间建议控制在2秒内。
主流监控方案对比与选型
| 方案类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 云厂商自带(如阿里云云监控) | 无需维护,开箱即用 | 成本随检测频率增加,定制性差 | 中小型业务快速启动 |
| 开源系统(Prometheus+Grafana) | 灵活,可自定义告警规则 | 需搭建维护环境,学习曲线陡 | 中大型团队或私有化部署 |
| 自定义脚本 | 完全可控,成本低,可快速定制 | 需编写、维护脚本代码 | 有运维开发能力的团队 |
选型建议:对于多数企业,初期使用自定义脚本+简单调度(如crontab)即可满足需求,后续再迁移至成熟监控系统。
基于Shell脚本的简易监控(含代码)
以下是一个可直接运行的Shell脚本,检测目标网站是否可达,并记录结果。
#!/bin/bash
# 网站可用性监控脚本 v1.0
# 注意:请将example.com替换为你的目标域名
URL="https://example.com"
LOG_FILE="/var/log/website_monitor.log"
TIMEOUT=10 # 超时时间(秒)
# 获取当前时间
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
# 使用curl检测,-o忽略响应体,-s静默,-w输出HTTP状态码
HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" --connect-timeout $TIMEOUT $URL)
if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 301 ] || [ "$HTTP_CODE" -eq 302 ]; then
echo "$CURRENT_TIME 🟢 可用 (HTTP $HTTP_CODE)" >> $LOG_FILE
else
echo "$CURRENT_TIME 🔴 不可用 (HTTP $HTTP_CODE)" >> $LOG_FILE
# 可在此处触发报警(如发送邮件)
fi
# 保留最近1000行日志,避免日志无限增长
tail -n 1000 $LOG_FILE > /tmp/monitor_tmp.log && mv /tmp/monitor_tmp.log $LOG_FILE
部署步骤:
- 将脚本保存为
monitor.sh,赋予执行权限chmod +x monitor.sh - 添加到crontab:
*/5 * * * * /path/to/monitor.sh(每5分钟执行一次)
注意:若检测IP黑名单或动态页面,需添加cookie或header参数。
使用Python实现进阶监控脚本
Python脚本支持更复杂的逻辑,如解析JSON响应、检测页面关键词、计算响应时间分布等。
#!/usr/bin/env python3
# 进阶版:检测页面内容与响应性能
import requests
import time
import logging
from datetime import datetime
# 配置
TARGET_URL = "https://example.com"
EXPECTED_KEYWORD = "正常" # 期望页面包含的关键词
CHECK_TIMEOUT = 5 # 秒
LOG_FILE = "monitor_advanced.log"
# 日志配置
logging.basicConfig(filename=LOG_FILE, level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
def check_website():
try:
start_time = time.time()
response = requests.get(TARGET_URL, timeout=CHECK_TIMEOUT, verify=False) # 忽略SSL证书验证
duration = time.time() - start_time
if response.status_code == 200:
if EXPECTED_KEYWORD in response.text:
logging.info(f"✅ 成功 - 状态码{response.status_code}, 耗时{round(duration,2)}秒, 关键词匹配")
else:
logging.warning(f"⚠️ 页面返回200但缺少关键词 '{EXPECTED_KEYWORD}'")
else:
logging.error(f"❌ 异常状态码: {response.status_code}, 耗时{round(duration,2)}秒")
except requests.exceptions.Timeout:
logging.error("❌ 连接超时")
except requests.exceptions.ConnectionError:
logging.error("❌ 无法连接(DNS或网络故障)")
except Exception as e:
logging.error(f"❌ 未知错误: {str(e)}")
if __name__ == "__main__":
check_website()
优势:可以灵活添加性能数据统计(如平均响应时间、分位数)、SSL证书过期检测、甚至模拟用户登录操作。
集成报警通知:邮件、短信与钉钉
重要提示:报警是监控的灵魂,无人响应的监控毫无意义。
1 邮件报警(Linux内置)
在Shell脚本中添加:
echo "站点 $URL 在 $CURRENT_TIME 不可用" | mail -s "网站宕机告警" admin@example.com
需提前配置sendmail或postfix。
2 钉钉机器人Webhook(推荐)
Python示例:
import requests, json
def send_dingtalk(message):
webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" # 请替换实际token
headers = {'Content-Type': 'application/json'}
data = {"msgtype": "text", "text": {"content": f"🔥{message}"}}
requests.post(webhook_url, headers=headers, json=data)
3 企业微信/Telegram
类似钉钉,使用对应API接口。注意:所有API密钥不应硬编码在脚本中,建议存入环境变量(如 os.getenv('WEBHOOK_URL'))。
脚本优化:并发检测与日志轮转
1 多站点并发检测
对于大型业务(大于10个站点),串行检测会耗时过长,Python多线程实现:
from concurrent.futures import ThreadPoolExecutor, as_completed
def check_site(url):
# ... 检测逻辑 ...
return url, status
urls = ["https://site1.com", "https://site2.com"]
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(check_site, url): url for url in urls}
for future in as_completed(futures):
url, status = future.result()
print(f"{url}: {status}")
2 日志轮转(避免磁盘占满)
推荐做法:使用Linux的logrotate工具,在 /etc/logrotate.d/ 下创建配置文件:
/var/log/website_monitor.log {
daily
rotate 30
compress
missingok
notifempty
}
常见问题与问答
Q1:为什么我的curl脚本检测总是返回200,但实际网站已经挂了?
A:部分服务会返回“正常”的HTTP状态码,但实际业务已崩溃(如数据库连接失败),建议在Python脚本中加入内容验证(如检查关键词或JSON字段)。
Q2:监控频率设置多少合适?
A:一般5分钟一次,如果对可用性要求极高(如金融交易),可缩短为1分钟,但需注意API限流和服务器压力。
Q3:脚本检测到不可用,但手动访问是正常的?
A:可能原因是脚本所在服务器网络不通(如被防火墙拦截),或脚本里 verify=True 导致SSL证书验证失败,建议增加重试机制(如连错3次才告警)。
Q4:如何处理告警风暴(同一问题多次触发)?
A:实现告警抑制:首次检测到故障后,5分钟内不再重复发送告警,可在Python中用time模块记录上次故障时间,或使用外部状态文件。
总结与最佳实践建议
编写一个可靠的网站监控脚本需要考虑以下维度:
- 准确性:结合HTTP状态码与内容验证,避免误报
- 韧性:处理网络波动、超时、SSL错误等异常场景
- 可观测:通过日志与告警形成闭环
- 低成本:优先使用Shell+curl,复杂需求再上Python
最终实践清单:
- 至少监控两个地域(如本地服务器+第三方检测服务)
- 告警分级:红色(严重宕机),黄色(响应变慢)
- 每周审查日志,调整监控阈值
- 配合CDN监控与服务器自身指标(如CPU、内存)
通过以上脚本和策略,你将能构建一套成本极低但高效的网站可用性监控体系,保障业务连续性。