网络接口健康检查 是做什么的?
当网络症状可能由物理链路、交换机端口、线缆、光模块、双工设置或接口拥塞引起时,使用此技能。
使用时机
- 主机或 VLAN 出现丢包、延迟尖峰或间歇性可达性问题。
- 交换机或路由器接口显示 CRC、runts、giants、丢包、重置或 flap。
- 在更换硬件前需要对比链路两端计数器。
- 变更窗口需要接口计数器变更前后的证据。
- 监控报告
ifInErrors、ifOutErrors或ifOutDiscards持续上升。
工作原理
接口计数器是证据,但趋势比绝对数值更重要。先捕获基线,等待一个测量间隔,再次捕获,然后比较增量。
show interfaces <interface>
show interfaces <interface> status
show logging | include <interface>|changed state|line protocol
在 Linux 主机上:
ip -s link show <interface>
ethtool <interface>
ethtool -S <interface>
计数器参考
| 计数器 | 含义 | 常见原因 |
|---|---|---|
| CRC | 接收帧校验和失败 | 线缆损坏、光纤污染、光模块故障、双工不匹配 |
| input errors | 汇总的接收侧错误 | 在得出结论前检查子计数器 |
| runts | 尺寸小于最小以太网帧的帧 | 双工不匹配、冲突域、NIC 故障 |
| giants | 尺寸超过预期 MTU 的帧 | MTU 不匹配或巨型帧边界问题 |
| input drops | 设备无法接收入站数据包 | 突发流量、超额认购、CPU 路径、队列压力 |
| output drops | 出口队列丢弃的数据包 | 拥塞、QoS 策略、上行链路容量不足 |
| resets | 接口硬件复位 | 接口 flap、keepalive、驱动程序、光模块、电源 |
| collisions | 以太网冲突计数器 | 半双工或协商不匹配 |
诊断流程
CRC 或输入错误
- 确认计数器在持续增长,而不仅仅是历史数据。
- 检查链路两端。接收侧错误通常指向到达该侧的信号问题,而不一定是报告错误的端口本身。
- 更换跳线或清洁/更换光纤和光模块。
- 确认两端的速率/双工设置匹配。
- 检查日志中相同时间戳附近的 flap 事件。
丢包
- 区分输入丢包和输出丢包。
- 将接口速率与容量进行比较。
- 检查 QoS 策略、队列计数器以及该链路是否是一个超额认购的上行链路。
- 队列调优是次要的。首先证明链路是否拥塞。
双工和速率
在现代以太网链路上,如果两端都支持,优先使用自动协商。如果一端必须固定配置,则两端都要显式配置并记录原因。绝不要在一端混合固定速率/双工而在另一端使用自动协商。
show interfaces <interface> | include duplex|speed
安全解析示例
将每个接口块从头一个标识符到下一个标识符切片。不要使用任意字符窗口;大的接口块可能导致计数器被遗漏或错误分配给其他端口。
import re
from typing import Any
HEADER_RE = re.compile(
r"^(?P<name>\S+) is (?P<status>(?:administratively )?down|up), "
r"line protocol is (?P<protocol>up|down)",
re.I | re.M,
)
ERROR_RE = re.compile(r"(?P<input>\d+) input errors, (?P<crc>\d+) CRC", re.I)
DROP_RE = re.compile(r"(?P<output>\d+) output errors", re.I)
DUPLEX_RE = re.compile(r"(?P<duplex>Full|Half|Auto)-duplex,\s+(?P<speed>[^,]+)", re.I)
def parse_show_interfaces(raw: str) -> list[dict[str, Any]]:
headers = list(HEADER_RE.finditer(raw))
interfaces = []
for index, header in enumerate(headers):
end = headers[index + 1].start() if index + 1 < len(headers) else len(raw)
block = raw[header.start():end]
errors = ERROR_RE.search(block)
drops = DROP_RE.search(block)
duplex = DUPLEX_RE.search(block)
interfaces.append({
"name": header.group("name"),
"status": header.group("status"),
"protocol": header.group("protocol"),
"duplex": duplex.group("duplex") if duplex else "unknown",
"speed": duplex.group("speed").strip() if duplex else "unknown",
"input_errors": int(errors.group("input")) if errors else 0,
"crc_errors": int(errors.group("crc")) if errors else 0,
"output_errors": int(drops.group("output")) if drops else 0,
})
return interfaces
示例
一个交换机端口上的 CRC
- 捕获本地端口的计数器。
- 捕获连接的对端端口的计数器。
- 在更改路由或防火墙规则之前更换线缆或光模块。
- 仅在记录基线后清除计数器。
- 在固定时间间隔后重新检查。
互联网慢但局域网正常
- 检查 WAN 接口的丢包/错误。
- 检查 LAN 上行链路的利用率和输出丢包。
- 如果 WAN 链路干净但吞吐量仍然低,检查网关 CPU。
- 在责怪上游服务之前,先比较有线和无线测试结果。
反模式
- 在保存基线前清除计数器。
- 只查看链路的一端。
- 没有时间窗口就假设所有历史 CRC 都是活跃问题。
- 在一端混合自动协商而在另一端使用固定速率/双工。
- 在检查拥塞之前就将输出丢包视为线缆问题。
参见
- 智能体:
network-troubleshooter - 技能:
network-config-validation - 技能:
homelab-network-setup