ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

云服务器丢包排查:用操作系统控制台从现象到根因

云服务器丢包排查:用操作系统控制台从现象到根因 先别急着登SSH也别急着提工单。云服务器一出现网络丢包很多人的第一反应是去改内核参数、重启网卡甚至怀疑是机房故障。但我近几年处理阿里云 ECS 的线上问题越来越依赖一个被低估的入口——阿里云控制台本身。尤其是控制台里那个直接能敲命令的“操作系统控制台”很多时候不需要第三方终端甚至不用公网 IP就能把丢包问题从现象定位到根因再顺手修掉。这篇文章就把我常用的一套排查思路和操作细节完整拆开包括哪些命令是在忽悠你哪些参数改完真的有奇效以及为什么说“一招”就能解决大部分丢包场景。适合正在被网络抖动、延迟忽高忽低、业务偶发超时折磨的运维和开发者。看完你至少能知道控制台里该点哪里、该敲什么、敲完看什么以及哪些问题其实根本不用碰服务器。1. 先把丢包这件事说透不是所有丢包都该修1.1 丢包到底丢在哪一层网络丢包字面意思就是数据包在传输过程中没有被送达。但“丢包”这三个字背后可能是完全不同的病因自己吓自己之前先判断一下丢包发生的位置。最常见的丢包点是物理链路比如光纤、交换机、机房内部网络设备。这类丢包通常表现为从你本机到阿里云公网 IP 的整条链路都不稳定ping的丢包率从第一跳到最后一路都在跳。因为云服务器所在机房的网络基础设施我们碰不到这类问题只能靠工单或者控制台里的“网络诊断”来反馈。另一类丢包发生在服务器自身比如网卡驱动层丢弃、协议栈处理不过来、TCP 连接队列满、防火墙拦截后悄悄丢弃。这类丢包往往是应用感知最明显的因为别人访问你的时候偶发超时但你ping外网可能是好的。这也是我为什么强调要用操作系统控制台去看服务器内部视角的原因。还有一类是安全组和带宽限制造成的“假丢包”。安全组规则把包拦了客户端看到的同样是 timeout实际上服务端根本没收到。或者带宽被占满内核协议栈被迫丢包。这类问题控制台里的监控图表直接就能看出来不需要进服务器。所以排查丢包的第一步永远是确定方向是链路问题、服务器内核问题还是策略问题。方向错了改再多内核参数都是白忙活。1.2 为什么丢包会引发连锁故障丢包不是简单“慢一点”的问题对 TCP 业务来说丢包会触发拥塞控制算法降低发送窗口重传超时进而放大延迟。对 UDP 业务来说丢包就是实打实的数据缺失音视频卡顿、实时消息丢失。对 HTTP 服务来说丢包可能表现为页面加载慢、接口偶发 5xx。更麻烦的是很多丢包是间歇性的。白天好好的晚上高峰就丢监控还抓不到。等到你去排查的时候问题又消失了。这时候如果你没有在控制台里保留现场没有监控数据就只能靠运气。这也是我在文章开头强调“先别登 SSH”的原因——你需要一个能快速打开、能保留历史记录的入口操作系统控制台恰好满足。我自己习惯的做法是遇到丢包反馈先打开 ECS 控制台的“网络诊断”看一眼最近 15 分钟的丢包率和流量图。如果控制台显示的是 0%那问题大概率在服务器内部或者更上层。如果控制台都显示丢包说明链路已经比较严重了再进服务器看内部指标才有意义。2. 操作系统控制台比 SSH 更值得优先用的运维入口2.1 它到底是什么很多人在阿里云 ECS 实例详情页看到了“远程连接”这个入口点进去会有一个类似浏览器终端的界面这就是常说的 Workbench也是我这里说的“操作系统控制台”。它不是单独的产品而是集成在 ECS 控制台里的运维组件。比起传统的 SSH它的优势很明显不依赖公网 IP 和安全组放行。即使你的服务器没有公网 IP或者安全组禁止了 22 端口只要控制台能访问你就能登录。自带审计日志和操作记录。出了问题能查到谁做了什么比自己在终端里敲命令更可控。支持文件上传下载和命令批量下发。特别是批量处理多台机器时比一台台 SSH 快太多。首次登录不需要密码。可以用 RAM 用户的权限直接拉起一个会话避免密码泄露和临时授权问题。如果你的服务器只是偶尔需要应急操作其实没必要给公网开放 22 端口用操作系统控制台就足够了。我遇到过一次比较极端的情况某台机器因为 iptables 规则把自己的 SSH 端口封了公网怎么都登不上去最后就是靠控制台里的 VNC 登录进去修复的。这种场景下操作系统控制台不是“备用方案”而是唯一的救命通道。2.2 控制台里到底有什么可用打开 ECS 实例详情页和网络排查相关的入口大致有三类网络诊断/连通性诊断控制台会从多个探测点检测你实例的公网连通性能看到丢包率和时延曲线。这个功能适合做第一层判断但它的粒度比较粗只能定位到“是不是公网链路有问题”。云监控看实例的带宽使用率、TCP 连接数、丢包计数等基础指标。这些数据来自云监控插件能帮你确认是不是带宽打满。远程连接Workbench也就是操作系统控制台能执行任意命令查看系统日志、网卡统计、内核参数。这是做深入定位的关键。很多人不知道的是操作系统控制台里还能直接运行云助手命令。云助手和 Workbench 的区别在于Workbench 就像你人坐在服务器前面云助手则是脚本化的命令下发通道适合批量执行、定时执行、甚至借助 OOS运维编排编写整个修复流程。所以我的建议是应急排查用 Workbench 交互敲命令批量修复用云助手批量执行脚本。两者配合基本能覆盖所有丢包排查场景。2.3 为什么它能“一招”解决丢包说回标题里的“一招”。我总结的“一招”并不是指某条神秘命令而是指把排查视角切换到操作系统控制台这个动作本身。什么意思很多新手排查丢包时习惯在本地电脑上ping服务器看到丢包就认为是服务器故障。但如果你直接进入操作系统控制台在服务器本机执行ping网关再ping外网你能立刻区分丢包到底发生在服务器的出口还是入口。同时你还能通过ethtool -S看到网卡驱动层面的丢包计数通过/proc/net/snmp看到内核协议栈的丢包计数。这些数据在本地电脑上是看不到的。只有站在服务器内部才能分清哪一段在丢。更进一步操作系统控制台提供了WebSocket 长连接的登录通道即使网络抖动导致 SSH 频繁断连控制台会话依然能保持。对排查“断断续续丢包”这种问题非常有用——你不需要反复重连可以开着监控命令观察直到抓到问题发生的那一瞬间。3. 核心实操一次完整的丢包定位过程3.1 第一步用控制台确认现象假设现在有人反馈“服务器 ping 不通了偶尔通偶尔断”。你先别在本地 ping 个不停那只能看到表象。登录操作系统控制台执行ping -c 100 -i 0.2 网关IP这里网关 IP 可以从控制台实例详情里的“专有网络”信息里查到也可以在系统内通过ip route获取。如果到网关就丢包说明问题出在后端物理网络或服务器网卡如果到网关稳定再往外 pingping -c 100 -i 0.2 223.5.5.5这步是为了区分“机房内部网络”和“公网链路”。很多时候本地到网关没问题但 ping 公网丢包大概率是公网链路的拥塞或者运营商路由问题而不是服务器本身的问题。一个容易踩的坑ping公网时部分运营商节点不会响应 ICMP这会造成“假丢包”。所以更可靠的判断方式是ping一个固定的云上 IP比如阿里云 DNS 223.5.5.5。如果它丢包那么再测一个非阿里云的 IP 做对比。3.2 第二步看网卡统计到底丢了谁如果确认现象存在下一步是用ethtool查看网卡层面的丢包。ethtool -S eth0 | grep -E drop|discard|error|rx_errors|tx_errors不同型号的网卡输出字段不一样但关注点就几类rx_errors表示接收错误通常和网卡硬件、驱动、链路质量有关。rx_dropped表示驱动接收后因为资源不足而丢弃比如环形缓冲区满。tx_dropped表示发送失败被丢弃常见于 ARP 解析失败或拥塞。rx_missed表示网卡 FIFO 溢出说明硬件来不及处理通常要调整 ring buffer。我见过最典型的情况是rx_dropped持续增长但rx_errors几乎为零。这说明网卡本身没问题是内核没有及时把包从网卡队列里取走也就是处理能力跟不上了。这时候改什么tcp_mem、tcp_tw_reuse都没用真正要改的是中断合并策略和队列深度。操作系统控制台的好处是你可以在这里直接开一个长会话用watch -n 1 ethtool -S eth0 | grep drop持续观察。丢包是瞬间发生的如果不盯着看很容易错过证据。3.3 第三步看协议栈是不是在悄悄丢ethtool看的是网卡和驱动接下来还要看内核协议栈。cat /proc/net/snmp | grep -E Ip|Tcp重点关注几个字段Ip: InDiscardsIP 层丢弃的包可能因为路由表异常、分片重组失败。Ip: InHdrErrorsIP 头错误通常说明有非法包攻击或者网卡驱动异常。Tcp: ListenOverflowsTCP 半连接队列溢出丢弃新连接。Tcp: ListenDrops同上只是统计口径不同。Tcp: RetransSegs重传段数量重传率过高说明链路质量问题。如果你看到ListenOverflows在增长那丢包主题根本不是网络而是后端服务处理不过来。常见的是 Nginx 或 Java 应用线程池被打满新的连接直接被内核拒绝。这时候修复方式不是调网络而是增大 backlog 队列、优化应用并发参数。比如临时增大监听队列echo 65535 /proc/sys/net/core/somaxconn但这只是临时缓解根本解法还是看应用本身。本文开头说的“丢包”其实包含这一类“连接被丢弃”在控制台里不要把注意力全放在 ICMP 上TCP 连接层面同样会丢。3.4 第四步描点定位公网链路如果服务器内部检查都正常网卡没丢、协议栈没丢却依然有丢包那就要看公网链路上的哪一跳丢了。在操作系统控制台里装上并执行mtryum install -y mtr mtr -r -c 100 223.5.5.5mtr会同时输出每一跳的丢包率和延迟。关键看两点如果丢包只出现在最后一跳其他节点都是 0%那说明是目标机器本身的问题。如果丢包从中间某一跳开始出现并持续到最后那可能是中间运营商链路的问题也可能是因为那一跳的节点为了响应 ICMP 有限速策略并不代表真实数据包丢。我总结的经验是看 mtr 不要只看某一跳的丢包率要看下一跳是否继续丢包。如果下一跳恢复 0%那说明之前那跳只是不受理 ICMP真实数据是通的如果后续所有跳都丢才是真正的链路故障。这一步在本地电脑上同样可以做但操作系统控制台的视角能排除“本地上行链路”的干扰。因为你是从服务器内部往外探测所以丢包数据更干净。3.5 收敛结论把问题归类完成上面四步基本能把问题归类为四种现象归类下一步到网关丢包网卡/物理链路检查网卡统计、重启网卡、工单反馈到公网 IP 丢包但网卡正常运营商链路用阿里云网络诊断抓取数据或换 EIP网卡 rx_dropped 高资源瓶颈调整 ring buffer、中断合并、网卡多队列ListenOverflows 增长应用瓶颈调应用并发、增大 backlog、优化代码到这里“丢包”就不再是一个模糊的“网络不好”而是一个具体的、可执行的修复方向。下面重点展开在操作系统控制台里真正动手修复的几种场景。4. 几个特别值得动手的修复方案4.1 网卡环形缓冲区太小导致丢包这是比较常见的一种。网卡收到数据后会先放进一个环形队列ring buffer内核再从中取包处理。如果队列太小或者瞬间流量太大队列满了就把包丢了。查看当前队列大小ethtool -g eth0输出里RX那行的Current就是当前值一般云服务器默认可能是 256 或者 512。如果rx_dropped一直在涨先把队列调大ethtool -G eth0 rx 4096 tx 4096调整完之后再观察一段时间确认rx_dropped不再增长。注意这个修改重启后会失效所以确认有效之后要写入开机配置。不同的发行版方式不同RedHat 系可以写/etc/rc.local或者用 systemd 单元甚至通过 udev 规则。这里建议用/etc/sysconfig/network-scripts/ifcfg-eth0里的ETHTOOL_OPTS方式但不同云厂商的镜像可能不支持更通用的办法是写一个 systemd servicecat /etc/systemd/system/ethtool-ring.service EOF [Unit] DescriptionSet eth0 ring buffer Afternetwork.target [Service] Typeoneshot ExecStart/usr/sbin/ethtool -G eth0 rx 4096 tx 4096 RemainAfterExityes [Install] WantedBymulti-user.target EOF systemctl enable ethtool-ring.service systemctl start ethtool-ring.service注意ring buffer 不是越大越好。越大占用内存越多而且如果突发流量大到连 4096 的队列都填满那说明问题不在队列大小而在中断处理。调完之后一定要结合软中断观察。4.2 软中断不均导致单核被打满很多丢包是“看起来莫名其妙”的流量不高但核 0 的软中断si占用 100%其它核闲着。这就会导致网卡中断集中在一个核上处理不过来然后丢包。排查方式cat /proc/softirqs | grep NET观察 NET_RX 在各个 CPU 上的分布。如果集中在 CPU0而业务流量很大那就需要启用网卡多队列或者调整 RPSReceive Packet Steering。启用 RPS 的一种快速方法echo ffffffff /sys/class/net/eth0/queues/rx-0/rps_cpusffffffff代表使用前 32 个 CPU 核需要根据你的 vCPU 数量调整不要超了。同时调整 RPS 的流表大小echo 4096 /sys/class/net/eth0/queues/rx-0/rps_flow_cnt在操作系统控制台里操作很方便的一点是你不需要依赖第三方终端也不需要担心调整过程中 SSH 会话断开。即使调整了网络参数导致 SSH 短暂断开控制台的 WebSocket 通道往往还能保持这是非常实际的救援能力。另外检查中断合并。网卡中断合并coalesce是让网卡攒一批中断再通知 CPU而不是每来一个包就打断一次。适当的合并能显著降低 CPU 占用和丢包。查看当前合并参数ethtool -c eth0如果rx-usecs是 0可以试着改成一个有界值ethtool -C eth0 rx-usecs 16 rx-frames 8这个参数的含义是每 16 微秒或每攒 8 个帧合并一次中断。具体数值要按流量模型调小包多就调小延迟大流量就调大合并。我自己在抓包场景下会关掉合并以便单包触发日常生产环境则保持一个较小的合并值减少 CPU 压力。4.3 TCP 半连接队列溢出导致新连接被丢如果丢包表现为“偶尔有用户连不上”而ping完全正常很可能是 TCP 连接队列溢出。查看当前溢出计数是否在增长grep -E ListenOverflows|ListenDrops /proc/net/netstatnetstat和snmp不同netstat文件里的字段没有第一行说明需要对照表头看。可以借助nstat命令nstat -az | grep -E TcpExtListen如果确认溢出临时增大监听队列echo 65535 /proc/sys/net/core/somaxconn同时要修改应用层。以 Nginx 为例listen 80 backlog65535;。如果应用是 Java Socket通常要调整ServerSocket的 backlog 参数。光调内核不改应用等于白调。半连接队列还有一个相关参数是tcp_max_syn_backlog如果ListenDrops出现且同步包SYN到达率很高适当调大这个值echo 65535 /proc/sys/net/ipv4/tcp_max_syn_backlog需要注意的是这些参数会瞬间生效但重启后失效。建议借助操作系统控制台里的“发送命令”功能批量写入持久化配置可以将参数写入/etc/sysctl.conf然后执行sysctl -p。我在批量运维时会先把命令保存为云助手脚本一次对几十台机器执行很快就能完成统一变更。这比一台台 SSH 快得多。4.4 安全组和带宽导致的假丢包有一种“丢包”是让人最抓狂的服务器内部一切正常网卡正常协议栈正常但用户就是访问不了。这时要立刻回到 ECS 控制台检查两件事安全组规则是否误拦了对应端口。常见的坑是入方向只放行了 80/443却没放行 8080或者来源 IP 写错了。公网带宽是否被打满。打开云监控看实例带宽的流入/流出速率如果达到带宽上限云盾和底层调度会直接限速表现就是丢包和超时。如果是云监控显示带宽跑满那不是内核问题而是业务流量超过规格。要么升级带宽要么做限流、加缓存或者排查是否有异常流量。很多用户遇到带宽打满时第一反应是“我程序有 bug”但实际可能是恶意扫描、日志采集程序失控或者某个服务没有做流量控制。在操作系统控制台里可以较快地看到当前连接占用ss -ntu | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -nr | head -20这个命令能清楚看到哪些远端 IP 占用了最多连接。如果某个 IP 的连接数异常巨大多半是扫描或攻击可以在安全组中直接封禁。另外ss -s可以快速看当前 socket 数量。如果 TIME_WAIT 上万那多半是连接释放太快但这通常不会直接丢包反而是端口被占用的风险更大这里不展开。4.5 一个完整的修复流程示例假设你登录控制台后看到ethtool -S eth0中rx_dropped在涨同时cat /proc/softirqs显示 NET_RX 集中在 CPU0。完整操作链路是先执行ethtool -G eth0 rx 4096 tx 4096扩大队列。执行ethtool -C eth0 rx-usecs 16开启中断合并。配置 RPS把软中断分散到多核。观察 5 分钟确认丢包计数增长是否停止。停止后把以上配置写成 systemd service 或开机脚本避免重启失效。持续观察云监控和业务指标确认无副作用。如果丢包的同时TCP 重传率很高还需要关联分析是不是链路质量或 MTU 问题。云服务器 MTU 一般默认 1500不要随意改。之前有人为了优化性能把 MTU 改成 9000结果有些路径不支持巨型帧反而导致丢包。这是个典型的“好心办坏事”。5. 常见问题与排查技巧实录5.1 常见问题速查表我在实际操作中把丢包问题按“是否服务器内部可见”分成两类。下面的表格总结了常见问题特征和处理方式现象可能原因排查命令/控制台入口处理方式本机 ping 网关丢包物理链路或网卡异常ethtool -S eth0联动控制台“网络诊断”并提交工单网卡 rx_dropped 高环形队列满或中断处理不过来ethtool -g、cat /proc/softirqs调大 ring buffer、开启 RPS、中断合并TCP 新连接被丢弃半连接队列溢出nstat -az | grep Listen调大 backlog、优化应用流量照常但访问超时安全组拦截ECS 控制台安全组列表检查规则、来源 IP 和端口带宽跑满后丢包带宽规格不足或异常流量云监控带宽图表、ss -ntu统计连接升级带宽或封禁异常 IP整条链路丢包且 mtr 显示多跳丢运营商链路抖动mtr -r -c 200联系阿里云支撑或尝试更换 EIPping 通但 TCP 丢包防火墙过滤、应用瓶颈iptables -L、协议栈统计检查防火墙策略和应用并发重启后参数失效未持久化查看启动配置使用 systemd service 或 sysctl.conf5.2 我在踩坑中总结出的 5 条经验第一不要一上来就改全局内核参数。我曾经在线上批量开启了tcp_tw_reuse确实减少了 TIME_WAIT 连接但随后出现了 TCP 连接复用导致的会话串扰业务方报了很多诡异 bug。后来才意识到丢包定位应该先观察局部数据再决定动哪个参数而且参数影响面要评估好。改参数前先sysctl -w临时改观察没问题再写入配置文件。第二控制台里的“重启实例”按钮是最后手段不是第一手段。有些同学遇到丢包直接重启实例。重启确实能暂时清掉一些计数让问题“看起来”消失但过两天又会复发而且重启会清空/proc下的实时数据让你丢失定位线索。尽量在丢包还在进行的时候抓住现场。第三不要忽略控制台的“网络诊断”结果。操作系统控制台看到的是服务器内部公网链路是否健康需要控制台的探测点协助。很多问题其实已经由云平台自动检测到了你在控制台的“网络”页面里能看到系统提示的丢包率和异常事件。养成定期查看这些页面的习惯比事后排查效率高得多。第四ethtool修改参数时要留意云平台虚拟网卡的限制。不是所有参数都能改成功。比如某些虚拟化环境不支持ethtool -G调整队列大小命令会返回错误。遇到这种情况不要硬改先通过云监控确认是不是平台侧限速或者直接提工单。强行调整可能造成驱动异常反而把问题搞复杂。第五抓包是验证丢包归属的唯一标准。在操作系统控制台里用tcpdump抓 ifcfg 队列并不难关键要会看。例如怀疑入方向丢包可以这样抓tcpdump -i eth0 -n tcp port 80 -c 100同时从另一个终端发起访问请求看看请求包是否被服务器收到。如果 tcpdump 能看到请求但应用没反应那就是应用层问题如果 tcpdump 都看不到那就是包根本没到服务器。这一步能彻底避开所有关于“中间链路”的争论。5.3 关于“一招”的最终定义这篇文章讲了很多命令但核心其实是一套决策框架。所谓“一招”不是让你死记某条命令而是让你遇事第一时间打开操作系统控制台在正确的位置执行正确的检查命令。当你掌握了从网关、网卡、协议栈、应用、链路这五个层面逐个排除的方法丢包就不再是玄学。我常用的检查组合拳可以存成一段脚本在控制台里直接执行echo 网卡统计 ethtool -S eth0 | grep -E drop|error|miss echo 协议栈统计 nstat -az | grep -E Listen|Retrans echo 软中断分布 cat /proc/softirqs | grep NET echo 连接队列 ss -lnt | awk NR1 {print $2} | sort | uniq -c这段脚本能在一分钟内给出基础证据足够你判断下一步该往哪个方向深入。把这段代码保存到云助手的自定义命令中以后任何一台机器出问题都能一键批量执行超级省事。最后再分享一个小技巧操作系统控制台里有个“文件管理”功能可以直接查看和下载/var/log/messages、/var/log/syslog等系统日志不需要用 vim 打开大文件。丢包排查时很多线索其实藏在网卡驱动报错里比如链路 down/up 抖动、固件异常。通过控制台把日志拉下来再用grep -i eth0过滤比在终端里一屏一屏翻高效得多。丢包问题之所以让人头疼是因为它横跨了网络基础设施、操作系统内核、应用层三个领域。但只要养成“先控制台、后系统内”的习惯用对工具你会发现大部分丢包都能在半小时内给出结论。希望这套方法能帮你少踩几次坑。
返回列表