Shell脚本如何监控网络连接数

wen 实用脚本 1

Shell脚本如何监控网络连接数:实战指南与最佳实践

目录导读

  1. 为什么需要监控网络连接数
  2. 核心监控原理:TCP连接状态解析
  3. 基础Shell脚本实现
  4. 进阶:实时告警与日志记录
  5. 常见问题与问答(FAQ)
  6. 总结与最佳实践

为什么需要监控网络连接数

网络连接数是服务器健康的关键指标,当连接数异常飙升时,通常意味着:

Shell脚本如何监控网络连接数

  • DDoS攻击:大量虚假连接耗尽系统资源
  • 程序漏洞:如数据库连接未释放,导致连接池耗尽
  • 服务过载:用户量激增但带宽不足

手动排查非常低效,而Shell脚本可以自动采集数据、设置阈值告警,让运维人员第一时间发现问题。


核心监控原理:TCP连接状态解析

Linux系统下,一切网络连接都记录在 /proc/net/tcp 或通过 netstat / ss 命令查看,关键的状态码包括:

状态码 含义 典型场景
ESTABLISHED 已建立连接 正常业务流量
TIME_WAIT 主动断开后的等待 高并发短连接
CLOSE_WAIT 被动断开未关闭 程序Bug(常见)
SYN_RECV 半连接 可能被SYN Flood攻击

监控脚本的核心逻辑就是:按状态统计连接数,并与阈值比较


基础Shell脚本实现

以下是一个可直接运行的监控脚本 monitor_connections.sh

#!/bin/bash
# 配置区
THRESHOLD_TOTAL=1000      # 总连接数告警阈值
THRESHOLD_TIME_WAIT=200   # TIME_WAIT告警阈值
THRESHOLD_CLOSE_WAIT=50   # CLOSE_WAIT告警阈值
LOG_FILE="/var/log/conn_monitor.log"
# 统计函数
count_connections() {
    local state=$1
    case $state in
        all)       ss -tun | tail -n +2 | wc -l ;;
        established) ss -tun state established | wc -l ;;
        time_wait)  ss -tun state time-wait | wc -l ;;
        close_wait) ss -tun state close-wait | wc -l ;;
        syn_recv)   ss -tun state syn-recv | wc -l ;;
    esac
}
# 获取数据
total=$(count_connections all)
established=$(count_connections established)
time_wait=$(count_connections time_wait)
close_wait=$(count_connections close_wait)
syn_recv=$(count_connections syn_recv)
# 告警逻辑
if [ "$total" -gt "$THRESHOLD_TOTAL" ]; then
    echo "[ALERT] $(date) 总连接数异常: $total > $THRESHOLD_TOTAL" >> $LOG_FILE
fi
if [ "$time_wait" -gt "$THRESHOLD_TIME_WAIT" ]; then
    echo "[ALERT] $(date) TIME_WAIT过多: $time_wait > $THRESHOLD_TIME_WAIT" >> $LOG_FILE
fi
if [ "$close_wait" -gt "$THRESHOLD_CLOSE_WAIT" ]; then
    echo "[ALERT] $(date) CLOSE_WAIT过多: $close_wait > $THRESHOLD_CLOSE_WAIT,可能程序未关闭连接" >> $LOG_FILE
fi
# 输出快照
echo "$(date) 状态: Total=$total EST=$established TW=$time_wait CW=$close_wait SYN=$syn_recv" >> $LOG_FILE

使用方法

  1. 保存为 .sh 文件并赋予执行权限:chmod +x monitor_connections.sh
  2. 添加到cron定时任务(如每分钟执行):crontab -e 添加 * * * * * /path/to/monitor_connections.sh

进阶:实时告警与日志记录

基础脚本只能记录日志,如果想实现实时告警(如发送邮件或钉钉消息),可以扩展如下:

# 告警函数(以邮件为例)
alert_email() {
    local subject=$1
    local body=$2
    echo "$body" | mail -s "$subject" your-email@example.com
}
# 在触发条件时调用
if [ "$total" -gt "$THRESHOLD_TOTAL" ]; then
    alert_email "连接数告警" "总连接数 $total 超过阈值 $THRESHOLD_TOTAL"
fi

日志轮转:使用 logrotate 管理日志文件,防止磁盘写满,在 /etc/logrotate.d/conn_monitor 中配置:

/var/log/conn_monitor.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

常见问题与问答(FAQ)

Q1: 为什么脚本里优先使用 ss 命令而不是 netstat

Assiproute2 工具包的一部分,性能远优于 netstat,尤其在连接数过万时,ss 的数据采集速度是 netstat 的10倍以上,多数现代Linux发行版都预装了 ss

Q2: 监控到CLOSE_WAIT过多,如何定位是哪个程序?

A:脚本只能发现症状,定位进程需要结合 lsof 命令:

ss -tun state close-wait | awk '{print $6}' | cut -d: -f1 | xargs -I{} lsof -i :{}

这会列出对应端口的进程名和PID。

Q3: 总连接数正常但TIME_WAIT很高,需要处理吗?

A:TIME_WAIT是TCP协议的正常状态,但过多(如超过2万)会占用系统内存和端口池,可以优化内核参数:

# 缩短TIME_WAIT等待时间
sysctl -w net.ipv4.tcp_fin_timeout=15
# 开启端口重用
sysctl -w net.ipv4.tcp_tw_reuse=1

注意:tcp_tw_recycle 在NAT环境下有副作用,建议用 tcp_tw_reuse 替代。

Q4: 脚本每天生成大量日志,怎么避免?

A:使用 -q 静默模式,只记录异常情况,或结合 logrotate 压缩旧日志,可以改为按小时滚动日志。


总结与最佳实践

通过Shell脚本监控网络连接数,关键在于:

  1. 精准统计:使用 ss 而非 netstat,按不同状态分类
  2. 阈值配置:根据业务场景动态调整(如促销活动时提高阈值)
  3. 自动化告警:结合邮件、短信或企业微信机器人
  4. 数据持久化:接入Prometheus或InfluxDB做趋势分析

最后提醒:脚本只是工具,真正的价值在于理解每个连接状态代表的问题

  • SYN_RECV 暴增 → 检查防火墙规则,考虑启用SYN Cookie
  • CLOSE_WAIT 堆积 → 代码层面修复未关闭的socket

建议将本文的脚本与你的监控平台(如Zabbix、Grafana)集成,实现可视化仪表盘,持续优化阈值,让脚本成为你运维的左膀右臂。


基于Linux内核TCP实现编写,适用于CentOS 7+、Ubuntu 20.04+、Debian 10+等主流发行版。)*

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