아래 그림과 같이 내 컴퓨터의 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 라우트 쇼 확인은 아래와 같습니다.
[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
웹 페이지에 대한 컬 히트는 약 30KB 의 데이터를 요청했습니다 .
[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 입니다.
답변
TCP가 어떻게 작동하는지 오해하고 있다고 생각합니다.
전송 된 각 패킷은 항상 수신기 창 (일명 RWIN) 및 선택적인 스케일링 계수를 알립니다 ( RFC 1323 참조).
보낸 사람은 RWIN에 지정된 양 보다 많은 양의 데이터를 승인하지 않고 보낼 수 없습니다 . 정체 창에 따라 보낸 사람이 RWIN을 채우도록 결정할 수 있습니다.
따라서 TCP 패킷에 공개되는 두 가지 정보 비트가 있습니다. 서버의 RWIN 및 클라이언트의 RWIN 이 두 그림은 혼잡 창의 최대 크기가 양쪽 끝에있을 수있는 크기를 나타냅니다.
파일 업로드에 대한 성능을 최적화하려고 할 때 서버의 RWIN이 흥미 롭습니다.
다운로드 속도를 결정하려고 할 때 클라이언트의 RWIN이 흥미 롭습니다.
이 숫자들 중 어느 쪽도 다른 쪽 끝에 정체 창을 공개하지 않습니다 .
내가 64K의 RWIN이있는 경우 SO, 서버의 혼잡 윈도우가 될 수 있습니다 모든 번호가 64K보다.
실제 혼잡 윈도우를 결정하는 유일한 방법은 패킷을 계산하는 것입니다.
내가 아는 경우 :
- 내 왕복 시간 (RTT)은 ~ 200ms입니다.
- 방금 100k의 리소스를 요청했습니다.
- 64k의 RWIN이 있습니다.
~ 200ms 이내에 1452 바이트 길이의 서버에서 2 개의 패킷을 다시 가져 오면 서버의 정체 창이 4356보다 작을 수 있습니다. 더 큰 경우 3 개의 패킷이 전송됩니다. IW가 10으로 설정되면 200ms 마크 주위에 10 개의 패킷 버스트가 나타납니다.
IW를 변경하고 변경 사항이 적용되었는지 확인 하려면 서버의 정체 창 크기를 추정하기 위해 패킷 을 계산해야 합니다.
SYN, SYN-ACK, ACK 직후의 대화를보고 혼잡 창이 이미 커져있는 대화의 중간을 보지 않도록해야합니다.
답변
서버 크기는 서버 초기화 창 크기 또는 클라이언트 RWIN 중 더 작은 것입니다. 5840은 Linux 2.6의 기본 RWIN이므로 클라이언트가 제한 요인 인 것 같습니다.
창 상자에서 사용해보십시오. Windows XP의 RWIN은 64k, 최신 버전 8k입니다.
출처 : http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/ (흥미로운 부분은 비디오 아래에 있습니다)
편집 : 답변을 확장하여 명확하게 만듭니다.
- TCP 핸드 셰이크에서 클라이언트는 최대 허용 창 크기를 전송하는 SYN 패킷을 서버로 보냅니다. (tcpdump 출력에서 알 수 있듯이 이들은 5840 바이트입니다)
- 서버는 이제 SYN ACK 및 동의하려는 창 크기로 응답합니다. 이 창 크기는 클라이언트가 제안한 것보다 작을 수 있으며 크지 않을 수 있습니다. 서버 구성 방법에 관계없이 해당 클라이언트의 서버 크기는 5840 바이트보다 클 수 없습니다.
- 고객은 ACK를 반환하고 행복하게 데이터를 교환합니다.
Edit2 : 질문에 추가 된 tcpdumps는 서버가 Google에 연결하고 클라이언트 역할을 수행함을 보여줍니다.