背景:拿到数据包时如何通过众多的数据,提炼出有效的网络分析信息,快速的进行定位排障。以下总结了一些 OSS 上传/下载慢的共性问题,提供大家参考。
排查问题之前让我们先来回顾一下 TCP 的基础知识
TCP 结构:
基础名词:
- Sequence Number是包的序列号,用来解决网络包乱序(reordering)问题。
- Acknowledgement Number就是ACK —— 用于确认收到,用来解决不丢包的问题。
- Window又叫Advertised-Window,也就是著名的滑动窗口(Sliding Window),用于解决流控的。
- TCP Flag,也就是包的类型,主要是用于操控TCP的状态机的。
- CWND ,也就是初始化发包控制的数量, ip ro 可以看到。 ip route 可以设置
- package flow ,数据包的流动增长。
常用抓包命令:
tcpdump -i 出口网卡 -s0 -v host \( 本地出口IP and 服务端IP \) -w filename.pcap
架构:
1)本地 PC -》 OSS 上传
2)本地 PC -》 OSS 上传
3)ECS -》 VPC 环境 -》OSS 下载
第一种架构:
首先根据 TCP/IP connect find important message
- client WS = 256
- MSS = 1452
- SACK = 1
- server WS = 0
- cwnd = 2
- length 1506
通过已知的信息我们可以先得出一些判断
- server 端不支持 WS,也就是一个往返 RTT 内最大传输是 64KB
- server support SACK,so transmission lose package,not all package
- cwnd tiny,起始传输会比较 slow,后续探测 reciver ACK 后,会指数递增
通过 RTT 可以看出来我们的网络稳定在 0.035
分析 TCP Stream 流图可以得知,延迟低,而且无丢包,从而可以得知并非是延迟丢包导致的传输速度慢。
分析发包的规律分布
通过以上几张连续的判断可以得知,客户端的 cwnd 是 2,而且每经过一个 RTT 后都会进行倍数的递增 2,4,6,8 最终稳定在 9 个,正常的 TCP 协议栈应该是以指数被递增,linux 是 64 ,windows 应该是到 256,同时我们也得知了对方是在一个 windows 系统上发包,协议栈和 Linux 的有很大区别。
接下准备分析为什么客户上传慢的原因:
RTT 是 35ms ,每个 RTT 只能传 9 个包,也就是 9*1506 / 35 = 378KB/s
总的时间 8876789/378/1024 = 23 + 卡顿 ~= 30S
所以整个发包速度慢也就是正常的
而服务端不支持 WS 的情况下,理论的最大传输速度也应该是:
根据 TCP 传输原理,理论最大传输速度 = WND / RTT = 64KB / 0.035 = 1828KB/s
1s 内有 1000/35 = 29 个 RTT, 29* 64 = 每个 RTT 最大传输量
但是现在每秒钟只能传输 1506 * 9 = 13554 = 13KB
综合结论客户端的 TCP 协议站传输是有问题。
第二种架构
老套路,先分析 TCP 三次握手中的基本信息。
- 服务端支持的 ws, 512 ,也就是单程 RTT 最大的传输量是 576 KB。
- 客户端的首发包数量是 2 个,也是成倍数递增 2,4,6,8,20 ...最终是 20。
- RTT 有持续增长的状态,因此三次握手的 RTT 可能不准确,我们需要计算一个加权后的 iRTT,最后得到是 40ms。
为什么延迟大的情况下,我们的传输速度反而比直传 OSS 稳定 0.035S 的要快呢?因为服务端支持 WS,也就是客户端在传输过程中的 package 可以持续滑动。
所以计算下来就是 434/(20*1498/0.04/1024) = 590ms
整个数据包传输完的时间 ~= 572ms
第三种架构
先从三次握手中获取价值信息
- 客户端、服务端都支持 WS
- RTT 稳定在 0.006
- send package 稳定在 88 个。
- 按照 WS 的支持一秒中最多能传的包是 88 * 1514 /0.006 =21MB/S
- 理论传输 1000/6 = 166,现在最大能传到 104,平均 88 ,可能存在 TCP 协议栈的问题。最终手段通过服务端调整了 OSS 机器的 TCP 协议栈,增大了 send package 和 CWND