监控网络连接数的脚本如何写

wen 实用脚本 1

从原理到实战,一篇精通

目录导读

  1. 为什么要监控网络连接数
  2. 核心监控指标解析
  3. 脚本编写基础:抓取连接数
  4. Linux环境下的Shell实现
  5. Windows环境下的PowerShell实现
  6. Python跨平台脚本实战
  7. 连接数异常告警与日志记录
  8. 常见问题与问答
  9. 总结与进阶建议

为什么要监控网络连接数

网络连接数(TCP/连接数)是服务器健康度的“体温计”,过高的连接数可能意味着:

监控网络连接数的脚本如何写

  • DDoS攻击:大量虚假连接导致服务拒绝
  • 程序异常:存在未释放的keep-alive连接
  • 性能瓶颈:连接池耗尽影响新用户访问

核心价值:通过脚本实时监控连接数,可以在问题发生前发出预警,避免服务中断,据调研,许多企业曾在高峰期因未监控连接数而出现服务雪崩,损失惨重。

核心监控指标解析

指标 含义 告警阈值参考
ESTABLISHED 已建立的连接数 >系统上限的70%
TIME_WAIT 主动关闭后的等待连接 >10000需关注
CLOSE_WAIT 被动关闭异常连接 持续增长需排查
SYN_RECV 半连接数 >500可能遭遇SYN Flood

关键概念:TCP连接状态是监控的核心,不同状态反映不同问题,TIME_WAIT过多通常与高并发短连接有关,而CLOSE_WAIT堆积则是程序bug的典型信号。

脚本编写基础:抓取连接数

无论使用哪种语言,核心命令只有一个——在Linux下通过ssnetstat统计特定状态的连接数:

# 统计ESTABLISHED连接数(推荐ss,性能优于netstat)
ss -t state established | grep -c "ESTAB"

注意ss是netstat的现代替代品,在大型系统上性能更优,如果你的服务器没有ss,使用netstat -an也可以,但注意netstat在部分发行版已被弃用。

Linux环境下的Shell实现

以下脚本实现每10秒监控、记录并自动告警:

#!/bin/bash
# monitor_connections.sh
LOG_FILE="/var/log/connection_monitor.log"
ALARM_THRESHOLD=1000
while true; do
    CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
    ESTAB_COUNT=$(ss -t state established 2>/dev/null | wc -l)
    TIME_WAIT_COUNT=$(ss -t state time-wait 2>/dev/null | wc -l)
    CLOSE_WAIT_COUNT=$(ss -t state close-wait 2>/dev/null | wc -l)
    echo "$CURRENT_TIME ESTAB:$ESTAB_COUNT TW:$TIME_WAIT_COUNT CW:$CLOSE_WAIT_COUNT" >> $LOG_FILE
    if [ "$ESTAB_COUNT" -gt "$ALARM_THRESHOLD" ]; then
        echo "$CURRENT_TIME ALARM: Established连接数 ${ESTAB_COUNT} 超过阈值 ${ALARM_THRESHOLD}" | tee -a $LOG_FILE
        # 发邮件或钉钉通知(此处可扩展)
    fi
    sleep 10
done

部署方式

chmod +x monitor_connections.sh
./monitor_connections.sh &
# 或使用 nohup 后台运行
nohup ./monitor_connections.sh &

Windows环境下的PowerShell实现

Windows系统使用netstat命令,但格式略有不同:

# monitor_connections.ps1
$logPath = "C:\logs\connection_monitor.log"
$alarmThreshold = 1000
while ($true) {
    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    # 统计ESTABLISHED状态(注意Windows下状态名不同)
    $estabCount = (netstat -an | Select-String "ESTABLISHED").Count
    $timeWaitCount = (netstat -an | Select-String "TIME_WAIT").Count
    $closeWaitCount = (netstat -an | Select-String "CLOSE_WAIT").Count
    "$time ESTAB:$estabCount TW:$timeWaitCount CW:$closeWaitCount" | Out-File $logPath -Append
    if ($estabCount -gt $alarmThreshold) {
        "$time ALARM: 超过阈值 $alarmThreshold" | Out-File $logPath -Append
    }
    Start-Sleep -Seconds 10
}

提示:Windows上的netstat输出速度较慢,如果连接数巨大(如5万以上),建议改用Get-NetTCPConnection(PowerShell 5.1+):

(Get-NetTCPConnection -State Established).Count

Python跨平台脚本实战

Python脚本可以同时支持Linux和Windows,且数据处理更灵活:

# monitor_connections.py
import subprocess
import time
import sys
from datetime import datetime
def get_connection_count(state="ESTAB"):
    """跨平台获取指定状态的连接数"""
    try:
        if sys.platform.startswith('linux'):
            # Linux下使用ss命令
            cmd = f"ss -t state {state.lower()}"
            output = subprocess.check_output(cmd, shell=True, text=True)
            return len([l for l in output.split('\n') if l.strip()])
        elif sys.platform == 'win32':
            # Windows下使用netstat
            output = subprocess.check_output('netstat -an', shell=True, text=True)
            return len([l for l in output.split('\n') if state in l])
        else:
            raise Exception("不支持的平台")
    except Exception as e:
        print(f"错误: {e}")
        return -1
def monitor_loop(interval=10, threshold=1000, log_file="connection.log"):
    while True:
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        estab = get_connection_count("ESTAB")
        time_wait = get_connection_count("TIME_WAIT")
        close_wait = get_connection_count("CLOSE_WAIT")
        log_line = f"{now} ESTAB:{estab} TIME_WAIT:{time_wait} CLOSE_WAIT:{close_wait}"
        print(log_line)
        with open(log_file, 'a') as f:
            f.write(log_line + '\n')
        if estab > threshold:
            alert_msg = f"{now} ALERT: Established {estab} > {threshold}"
            print(alert_msg)
            # 此处可集成邮件/API通知
        time.sleep(interval)
if __name__ == "__main__":
    monitor_loop()

运行方式

pip install --upgrade  # 无需额外依赖
python monitor_connections.py

连接数异常告警与日志记录

告警集成(以钉钉机器人为例):

import requests
def send_dingtalk_alert(msg, webhook_url="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"):
    data = {"msgtype": "text", "text": {"content": msg}}
    requests.post(webhook_url, json=data)

日志轮转:使用Python的logging.handlers.RotatingFileHandler自动分割日志,避免文件过大。

多维度监控建议

  1. 按IP统计:ss -tn src :80 dst :80 state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c 可找出异常IP
  2. 按端口分析:监控特定端口(如80/443)的连接分布

常见问题与问答

Q:为什么我的ss命令返回0个连接? A:通常是因为没加-t参数。ss默认显示所有套接字,加上-t只显示TCP,另外请检查是否有root权限(某些发行版需要sudo)。

Q:TIME_WAIT连接过多怎么处理? A:调优内核参数:

# 允许TIME_WAIT复用和快速回收(谨慎使用)
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout = 30" >> /etc/sysctl.conf
sysctl -p

注意:tcp_tw_recycle在Linux 4.12后已移除,因存在NAT问题。

Q:脚本如何做到不占用过多CPU? A:1) 使用sleep设置合理间隔(10-60秒);2) 避免在循环内频繁调用外部命令,可使用Python的pyshark库抓取实时数据包;3) 对于大型系统,可改为被动监听系统/proc文件系统。

Q:Windows脚本在服务器上无法运行? A:首先确保PowerShell执行策略允许:

Set-ExecutionPolicy RemoteSigned

某些Windows服务器(如Server Core)可能没有netstat命令,需要使用Get-NetTCPConnection替代。

总结与进阶建议

适合场景

  • 个人博客服务器:简单shell脚本即可
  • 企业业务系统:推荐Python脚本+日志+邮件/钉钉告警
  • 大型云原生架构:使用Prometheus+Grafana采集node_netstat_Tcp_CurrEstab指标

进阶玩法

  1. 历史趋势分析:将监控数据存入时序数据库(如InfluxDB)
  2. 自动化修复:当检测到CLOSE_WAIT堆积时,自动重启对应服务的Python子进程
  3. 分布式监控:通过SSH批量收集多台服务器的连接数(使用Paramiko库)

推荐工具对比: | 方法 | 优点 | 缺点 | |------|------|------| | 纯Shell | 轻量,无依赖 | 逻辑复杂时难以维护 | | Python | 跨平台、易扩展 | 需Python环境 | | 企业级监控 | 可视化、支持历史回溯 | 配置复杂 |

最后提醒:无论选择哪种方式,建议先在测试环境运行一周后再上生产,同时确认脚本不会因为资源消耗导致监控自身变成性能瓶颈,保持监控脚本健壮性——当脚本本身出现异常时,应能通过外部检测(如cron保活)自动恢复。


本文由自动化运维工程师根据实战经验整理,旨在帮助运维人员快速搭建可靠的网络连接数监控体系。

抱歉,评论功能暂时关闭!