上传文件 Empty reply from server

某客户返回海外上传文件特别慢,经常超时,于是进行排查

往接口发送文件

在 digitalocean 创建一个英国的服务器,然后进行测试

1.本地上传一个53k 的文件

   root@ubuntu-512mb-lon1-01:~# curl -T /usr/bin/passwd http://v0.api.upyun.com/file201503/passwd -u fangwenjun:xxxxxx-v
*   Trying 43.230.89.190...
* Connected to v0.api.upyun.com (43.230.89.190) port 80 (#0)
* Server auth using Basic with user 'fangwenjun'
> PUT /file201503/passwd HTTP/1.1
> Host: v0.api.upyun.com
> Authorization: Basic xxxxx==
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 54256
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
* Empty reply from server
* Connection #0 to host v0.api.upyun.com left intact
curl: (52) Empty reply from server

同时抓包

   root@ubuntu-512mb-lon1-01:~# tcpdump -i eth0 -nnXSs 0 'host 43.230.89.190 and port 80'  -w 3.cap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

发现往43.230.89.190发送 PUT 请求时出现Empty reply from server

本地测试路由

发现

ae-13.r30.tokyjp05.jp.bb.gin.ntt.net                                                                            52.9%    34  220.5 220.4 219.3 225.5   1.5

丢包率很大。

ping

root@ubuntu-512mb-lon1-01:~# ping 43.230.89.190
PING 43.230.89.190 (43.230.89.190) 56(84) bytes of data.
64 bytes from 43.230.89.190: icmp_seq=1 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=2 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=3 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=4 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=5 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=6 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=7 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=8 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=9 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=10 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=11 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=12 ttl=46 time=279 ms
64 bytes from 43.230.89.190: icmp_seq=13 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=14 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=15 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=16 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=17 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=18 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=19 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=20 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=21 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=22 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=23 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=24 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=25 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=26 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=27 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=28 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=29 ttl=46 time=275 ms
64 bytes from 43.230.89.190: icmp_seq=30 ttl=46 time=275 ms
^C
--- 43.230.89.190 ping statistics ---
31 packets transmitted, 30 received, 3% packet loss, time 30044ms
rtt min/avg/max/mdev = 275.387/275.678/279.776/1.025 ms

有点丢包,不过没超时的

数据包分析

发现大量TCP segment of a reassembled PDU wireshark

常见 tcp 报错

1.TCP previous segment lost (tcp先前的分片丢失)
到达分组中的序列号高于下一期望的序列号,指示至少一个段被丢弃/丢失。接收站通过针对其接收的每个附加分组发送重复ACK来纠正这种情况,直到发送方重传丢失的分组为止。

2.TCP acked lost segment(tcp应答丢失)
发送方发送了报文之后等待接收方给出ACK应答,在规定的等待时间内没有收到接收方的ACK会提示该信息。

3.TCP window update(tcp窗口更新)
TCP Window Update 是TCP通信中的一个状态,它可以发生的原因有很多,但最终归结于发送者传输数据的速度比接收者读取的数据还快,这使得接收端的在缓冲区必须释放一部分空间来装发送过来的数据,然后向发送者发送Windows Update,告诉给发送者应该以多大的速度发送数据,从而使得数据传输与接受恢复正常。

4.TCP dup ack(tcp重复应答)
Tcp Dup Ack xxx#y 代表了数据段丢失TCP状态,xxx代表数据丢失的位置,#后代表第几次丢失文。

一般来说是网络拥塞导致丢包,比如发送方的报文到达不了接收方,接受方收不到预期序列号的报文就会发送dup ack给发送方,发送方收到3个dup ack就会快速重传而不必等超时定时器。

一般来说是网络拥塞导致丢包,比如发送方的报文到达不了接收方,接受方收不到预期序列号的报文就会发送dup ack给发送方,发送方收到3个dup ack就会快速重传而不必等超时定时器。

5.TCP keep alive(tcp保持活动)
Keep-alive的机制可以检测死连接,TCP会在空闲了一定时间后发送数据给对方:

如果主机可达,对方就会响应ACK应答,就认为是存活的。
如果可达,但应用程序退出,对方就发RST应答,发送TCP撤消连接。

如果可达,但应用程序崩溃,对方就发FIN消息。

如果对方主机不响应ack, rst,继续发送直到超时,就撤消连接。这个时间默认是2小时。

6.TCP retransmission(tcp重传)

7.TCP port numbers reused(tcp端口重复使用)
TCP协议中规定,处在 TIME-WAIT 状态的TCP端,必须等待一定时长(协议建议2MSL),尽量确保TCP远端能够收到最后一次FIN分段的ACK确认。处于TIME-WAIT状态的TCP端,不能重建以同一四元组标识的TCP替身连接。该提示是由于客服端重新建立连接的端口号使用了仍然处在2MSL等待时长内的端口号

8.TCP fast retransmission (tcp快速重传)
TCP层检测到拥塞发生一般是两个条件之一,超时或者dup ack。

dup ack三次之后就进入快速重传/快速恢复 or 快速重传/慢启动

9.TCP spurious retransmission(tcp伪重传)
该提示是由于发送端重发了一个已经收到应答的报文段导致。

10.TCP segment of a reassembled PDU (重新组装的PDU的TCP片段)
TCP层收到上层大块报文后分解成段后发出去。

收到一个报文后如何确定它是一个”TCP segment”?如果有几个报文的ACK序号都一样,并且这些报文的Sequence Number都不一样,并且后一个Sequence Number为前一个Sequence Number加上前一个报文大小再加上1的话,肯定是TCP segment了,对于没有ACK标志时,则无法判断。