如何用tcping写脚本监控服务?
使用tcping编写服务监控脚本的核心在于通过自动化方式定期检测关键端口状态,并在异常时触发告警,从而实现对Web服务、数据库等关键业务的实时健康监测。
一、监控脚本设计基础
1. 监控脚本的核心功能
- 端口状态检测:定期使用tcping检查目标服务端口是否开放
- 响应时间监控:记录并分析服务响应延迟
- 异常告警机制:端口不可达或响应超时时通知相关人员
- 日志记录与分析:保存历史数据用于趋势分析和故障排查
2. tcping在监控中的优势
- 精准检测服务状态:相比ping,tcping能真实反映应用层服务是否可用
- 绕过ICMP限制:即使服务器禁用了ping响应,tcping仍能检测端口状态
- 提供毫秒级响应时间:可监测服务性能变化,而不仅是连通性
二、实用监控脚本示例
1. 基础Bash监控脚本(Linux/Windows WSL)
#!/bin/bash
# 服务监控脚本
# 配置参数
TARGETS=(
"www.example.com 443"
"192.168.1.100 80"
"db-server 3306"
)
CHECK_INTERVAL=30 # 检查间隔(秒)
MAX_FAILURES=3 # 最大连续失败次数
LOG_FILE="/var/log/service_monitor.log"
ALERT_EMAIL="admin@example.com"
# 检查函数
check_service() {
local target=$1
local host=$(echo $target | awk '{print $1}')
local port=$(echo $target | awk '{print $2}')
# 尝试连接端口
if tcping -t 5 $host $port &>/dev/null; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - SUCCESS: $host:$port is reachable" >> $LOG_FILE
return 0
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - FAILURE: $host:$port is unreachable" >> $LOG_FILE
return 1
fi
}
# 主监控循环
while true; do
for target in "${TARGETS[@]}"; do
local failures=0
# 尝试多次检测,避免误报
for i in {1..$MAX_FAILURES}; do
if ! check_service "$target"; then
failures=$((failures+1))
sleep 5
else
failures=0
break
fi
done
# 达到最大失败次数,触发告警
if [ $failures -ge $MAX_FAILURES ]; then
echo "【严重告警】$target 连续 $MAX_FAILURES 次检测失败!" | mail -s "服务中断告警" $ALERT_EMAIL
fi
done
sleep $CHECK_INTERVAL
done
2. 高级Python监控脚本
import subprocess
import time
import smtplib
from email.mime.text import MIMEText
from datetime import datetime
# 配置参数
TARGETS = [
("www.example.com", 443, "HTTPS服务"),
("192.168.1.100", 80, "Web服务"),
("db-server", 3306, "MySQL数据库")
]
CHECK_INTERVAL = 30 # 检查间隔(秒)
MAX_FAILURES = 3 # 最大连续失败次数
LOG_FILE = "/var/log/service_monitor.log"
ALERT_EMAIL = ["admin@example.com"]
SMTP_SERVER = "smtp.example.com"
SMTP_PORT = 587
SMTP_USER = "monitor@example.com"
SMTP_PASSWORD = "your_password"
def check_service(host, port):
"""使用tcping检查端口状态"""
try:
result = subprocess.run(
["tcping", "-t", "5", host, str(port)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
timeout=10
)
return result.returncode == 0
except Exception as e:
print(f"检查 {host}:{port} 时出错: {str(e)}")
return False
def send_alert(target, failures):
"""发送告警邮件"""
host, port, service_name = target
subject = f"【严重告警】{service_name} ({host}:{port}) 中断"
body = f"{service_name} ({host}:{port}) 连续 {failures} 次检测失败!\n\n"
body += "请立即检查服务状态和网络连接。"
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = SMTP_USER
msg["To"] = ", ".join(ALERT_EMAIL)
try:
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls()
server.login(SMTP_USER, SMTP_PASSWORD)
server.send_message(msg)
print(f"告警邮件已发送至 {', '.join(ALERT_EMAIL)}")
except Exception as e:
print(f"发送告警邮件失败: {str(e)}")
def main():
# 记录初始状态
status = {target: {"last_state": None, "failure_count": 0} for target in TARGETS}
while True:
for target in TARGETS:
host, port, service_name = target
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 检查服务状态
is_up = check_service(host, port)
# 记录到日志
with open(LOG_FILE, "a") as f:
f.write(f"{current_time} - {'UP' if is_up else 'DOWN'}: {service_name} ({host}:{port})\n")
# 状态变化检测
if is_up:
if status[target]["failure_count"] > 0:
print(f"{current_time} - 恢复: {service_name} ({host}:{port}) 已恢复")
with open(LOG_FILE, "a") as f:
f.write(f"{current_time} - 恢复: {service_name} ({host}:{port}) 已恢复\n")
status[target]["failure_count"] = 0
else:
status[target]["failure_count"] += 1
# 达到最大失败次数,触发告警
if status[target]["failure_count"] >= MAX_FAILURES and status[target]["last_state"] != "DOWN":
print(f"{current_time} - 告警: {service_name} ({host}:{port}) 连续 {MAX_FAILURES} 次检测失败!")
send_alert(target, MAX_FAILURES)
status[target]["last_state"] = "DOWN"
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
三、监控脚本的高级应用
1. 集成到系统服务
Linux系统服务配置示例:
# /etc/systemd/system/service-monitor.service
[Unit]
Description=TCPing Service Monitor
After=network.target
[Service]
User=root
ExecStart=/path/to/monitor_script.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
启用服务:
sudo systemctl enable service-monitor
sudo systemctl start service-monitor
2. 可视化监控增强
- Grafana + Prometheus集成:将tcping结果导入Prometheus,通过Grafana创建可视化仪表盘
- 日志分析:使用ELK栈(Elasticsearch, Logstash, Kibana)分析tcping日志,识别趋势和异常
- 响应时间图表:定期记录响应时间,生成趋势图表,便于性能分析
3. 企业级监控方案
标准化监控模板设计:
- 自动发现机制:通过LLD(低级发现)自动识别服务端口
- 多维度监控:结合网络层、传输层和应用层指标
- 智能告警:设置动态阈值,避免误报
- 故障自愈:检测到服务中断时自动尝试重启服务
四、最佳实践与注意事项
1. 脚本优化技巧
- 合理设置检查间隔:关键服务可设为15-30秒,非关键服务可设为5-10分钟
- 多轮检测机制:避免单次检测失败导致误报,建议设置3次重试
- 超时时间配置:根据网络环境设置合理超时时间,通常2-5秒
- 日志轮转:配置日志轮转策略,避免日志文件过大
2. 告警策略设计
- 分级告警:根据失败次数设置不同级别告警
- 1次失败:记录日志,不告警
- 3次失败:发送邮件告警
- 5次失败:触发短信/电话告警
- 告警抑制:服务恢复后发送恢复通知,避免持续告警
- 维护窗口:设置计划维护时间,避免误报
3. 安全与合规考虑
- 最小权限原则:监控脚本应使用最小必要权限运行
- 敏感信息保护:避免在日志中记录敏感信息
- 合规性检查:确保监控活动符合企业安全策略
- 审计跟踪:记录脚本执行和告警历史,便于审计
五、常见问题与解决方案
1. 脚本执行问题
- 权限不足:确保脚本有执行权限(
chmod +x script.sh) - 路径问题:使用绝对路径调用tcping,或确保PATH环境变量包含tcping位置
- 依赖缺失:Windows需确保tcping.exe在System32目录,Linux需安装tcping工具
2. 监控效果优化
- 误报问题:增加重试次数,延长检查间隔
- 漏报问题:缩短检查间隔,减少重试次数
- 性能影响:避免同时检测过多端口,分散检查时间
3. 高级场景处理
- 跨区域监控:在不同地理位置部署监控节点,使用tcping测试跨区域连接
- HTTPS服务验证:结合openssl检查SSL证书有效性
- 数据库连接测试:使用tcping检测数据库端口后,可进一步执行简单查询验证
提示:对于生产环境,建议将监控脚本与企业级监控系统(如Zabbix、Nagios或Prometheus)集成,利用其告警管理、可视化和历史数据分析功能,构建更完善的监控体系。定期审查监控数据,调整阈值和告警策略,确保监控系统持续有效。