nstat命令用于读取Linux内核中的SNMP累计计数器快照,默认情况下仅展示自上次运行以来的增量数值,而非历史累计总数。选项 -a 可显示绝对总值,-s 用于冻结历史记录,-r 则能重置计数器。过滤特定指标时直接使用计数器名称(如TcpRetransSegs)作为参数,而非 -p 选项。配合 -j 与 -z 参数可实现JSON结构化输出。

谈到Linux网络统计,许多用户首先想到的是抓包工具或接口流量计数器。然而,nstat采用完全不同的方式——它直接读取内核维护的SNMP计数器快照,本质上是内核协议栈内部累积的统计值。直接执行nstat命令默认输出的是“自上次执行以来的增量变化”,而非绝对总数。若混淆这一点,后续的数据分析将产生偏差。
默认输出怎么看:三列含义必须分清
典型的输出格式如下:IpInReceives 1248 0.0。这三列分别代表:第一列是计数器名称(对应SNMP OID名称),第二列为本次采样周期内的增量值(非累计总值),第三列是速率(每秒),基于默认的60秒窗口计算。若显示0.0则表示该周期内无变化。常见的误解是将第二列当作“当前连接总数”或“活跃连接数”,但实际上它与实时连接状态无关,仅反映协议栈收发行为的累计变化量。
nstat -a 和 nstat -s 的区别很关键
这两个选项决定了历史数据的更新方式,理解它们的差异直接影响后续结果的可靠性:
• nstat -a 显示从系统启动至今的绝对累计值,适合用于长期趋势基线对比;
• nstat -s 表示不更新历史记录,即便再次运行增量计算仍包含本周期数据——相当于冻结采样点,便于反复验证同一时间窗口;
• 默认行为(不带选项)会更新历史,因此连续执行两次时,第二次的增量仅包含第二次运行后的新变化;
• 如需重置所有计数器至归零状态,可使用nstat -r选项,但需注意该操作影响所有计数器且不可逆。
过滤特定协议或错误项:用 PATTERN 而不是 -p
许多文档提及-p tcp参数,但这其实是过时用法或源于与其他工具(如ss)的混淆。nstat正确的过滤方法是直接以关键词作为参数:
• 查询TCP重传:nstat TcpRetransSegs
• 查询UDP端口不可达:nstat UdpNoPorts
• 查询ICMP错误:nstat IcmpOutErrors
• 支持通配符,例如nstat TcpExt*可匹配所有以TcpExt开头的扩展计数器
• 多个关键词用空格分隔,如nstat TcpInSegs UdpInDatagrams
值得注意的是,不加-z参数时零值计数器不会显示,这可能导致遗漏关键静默指标——例如TcpRetransSegs长期为0才表明网络健康,恰恰是这种“不可见”数据最具价值。
导出与自动化:-j 和 -n 是实用组合
在监控脚本中,推荐组合使用-j(JSON格式输出)与-n(不输出到终端)配合定时任务:
• nstat -j -n可静默更新历史而不打印结果,适合配置为cron每分钟执行以积累数据;
• nstat -j TcpRetransSegs UdpNoPorts可按需提取结构化字段,便于jq解析;
• nstat -j -z | jq '.kernel.TcpRetransSegs'可稳定获取数值(添加-z防止字段缺失);
• 应尽量避免使用-d守护模式——该模式会在后台常驻并持续写入文件,但实际日志路径未标准化,不同发行版行为不一致,可能导致磁盘空间被意外占满。
实际上,nstat的难点并不在于记忆选项,而在于理解每个计数器对应内核中哪条路径、在何种条件下自增。例如,TcpExtTW表示time-wait socket的回收计数,但它并不等同于netstat -ant | grep TIME_WAIT | wc -l的结果——前者是回收计数,后者是瞬时数量。这种差异需要查阅内核源码或官方文档才能厘清,切勿轻信网上所谓“XX字段代表连接数”的二手解释。
