![Linux 启动缓慢:更改 IP 路由对初始窗口没有任何影响](https://linux22.com/image/577428/Linux%20%E5%90%AF%E5%8A%A8%E7%BC%93%E6%85%A2%EF%BC%9A%E6%9B%B4%E6%94%B9%20IP%20%E8%B7%AF%E7%94%B1%E5%AF%B9%E5%88%9D%E5%A7%8B%E7%AA%97%E5%8F%A3%E6%B2%A1%E6%9C%89%E4%BB%BB%E4%BD%95%E5%BD%B1%E5%93%8D.png)
我将机器中的 tcp 初始窗口更改为 10,如下所示
[user@site etc]$ sudo ip route change default via 17.255.209.1 dev eth0 proto static initcwnd 10
tcp_slow_start_after_idle
并按如下所示进行更改
[user@site etc]$ sudo sysctl -a | grep tcp_slow_start_after_idle
net.ipv4.tcp_slow_start_after_idle = 0
下面是 ip route show 确认信息
[user@site etc]$ ip route show
default via 17.255.209.1 dev eth0 proto static initcwnd 10
169.254.0.0/16 dev eth0 scope link metric 1002
17.255.209.0/24 dev eth0 proto kernel scope link src 17.255.209.19
现在,当我在网站上执行 tcpdump 时,我似乎没有看到初始窗口中的变化WIN/MSS 剩余 4默认。5840/1460=4
[user@site etc]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and port 80'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:17:45.048174 IP 21.101.151.198.45873 > 17.255.209.19.http: Flags [S], seq 2008673341, win 5840, options [mss 1460,sackOK,TS val 1724223146 ecr 0,nop,wscale 6], length 0
我对网页进行的 curl 操作请求了30 千字节数据的。
[user@machine ~]$ curl http://www.site.com/js/main.js > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 88212 100 88212 0 0 179k 0 --:--:-- --:--:-- --:--:-- 272k
我的方法可能存在什么问题?
核心
[user~]$ uname -r
3.0.4x86_64-linode21
作为更新,以下是我尝试的结果google.com
[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.google.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:20:28.033236 IP 17.255.209.19.42799 > 74.125.127.106.http: Flags [S], seq 3148947324, win 14600, options [mss 1460,sackOK,TS val 193695310 ecr 0,nop,wscale 4], length 0
如你看到的WIN/MSS 为 14600/1460=10在这种情况下
我尝试通过 curl 从服务器机器本身访问我的网站,结果如下:
[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.site.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:25:14.584338 IP 17.255.209.19.35008 > 17.255.209.19.http: Flags [S], seq 3894567470, win 32792, options [mss 16396,sackOK,TS val 193981861 ecr 0,nop,wscale 4], length 0
WIN/MSS 为 32792/16396=2在这种情况下
答案1
我认为您误解了 TCP 的工作原理。
发送的每个数据包始终会通告一个接收窗口(又名 RWIN)和一个可选的缩放因子,请参阅RFC 1323
发件人无权发送多于在没有得到确认的情况下,RWIN 中指定的数据量。根据拥塞窗口,发送方可以决定是否填充 RWIN。
因此,TCP 数据包中有两条信息是公开的。服务器上的 RWIN 和客户端上的 RWIN。这两个数字都决定了两端拥塞窗口的最大大小。
当我们尝试优化文件上传的性能时,服务器上的 RWIN 很有趣。
当我们尝试确定下载速度时,客户端上的 RWIN 很有趣。
这两个数字都不会公开另一端的拥塞窗口。
因此,如果我的 RWIN 为 64k,则服务器上的拥塞窗口可以是任何低于 64k 的数字。
确定实际拥塞窗口的唯一方法是计数数据包。
如果我知道:
- 我的往返时间(RTT)约为 200 毫秒。
- 我刚刚请求了 100k 的资源。
- 我的 RWIN 是 64k。
如果我在约 200 毫秒内从服务器收到 2 个长度为 1452 字节的数据包,则服务器上的拥塞窗口可能小于 4356,因为如果窗口更大,则会发送 3 个数据包。如果 IW 设置为 10,我将在 200 毫秒左右看到 10 个数据包的突发。
如果你更改了 IW 并想确认更改有效,你需要计算数据包以获得服务器上拥塞窗口大小的估计值。
请记住,您可能希望在 SYN、SYN-ACK、ACK 之后直接查看对话,以确保您没有查看对话的中间(拥塞窗口可能已经增长)。
答案2
窗口大小将取服务器初始化窗口大小或客户端 RWIN 中较小者。由于 5840 是 Linux 2.6 的默认 RWIN,因此您的客户端似乎是此处的限制因素。
从 Windows 框中尝试。Windows XP 的 RWIN 为 64k,较新版本为 8k。
来源:http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/(有趣的部分在视频下面)
编辑:扩大答案以使其更清晰:
- 在 TCP 握手中,客户端向服务器发送一个 SYN 数据包,发送其最大允许窗口大小。(正如 tcpdump 输出所示,这些是 5840 字节)
- 服务器现在用 SYN ACK 和它想要同意的窗口大小进行响应。此窗口大小只能小于客户端建议的大小,不能大于。无论服务器如何配置,它与该客户端的窗口大小都不能大于 5840 字节。
- 客户端返回 ACK,然后他们愉快地交换数据。
编辑2:问题中添加的 tcpdump 显示服务器打开与 google 的连接,并且本身充当客户端。