问题描述

最近进行了一次网络扩容和设备升级,该动作之后,Java程序就不能成功连接七牛的云服务。
利用七牛提供的qwebtest工具进行诊断,诊断报告输出如下:

> PING <

Command => ping -c 5 up.qiniu.com
PING nb-gate-up.qiniu.com (183.136.139.10) 56(84) bytes of data.
64 bytes from 183.136.139.10: icmp_seq=1 ttl=54 time=28.4 ms
省略

--- nb-gate-up.qiniu.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4032ms
rtt min/avg/max/mdev = 23.460/40.257/82.687/21.966 ms

> DIG <

Command => dig up.qiniu.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.6 <<>> up.qiniu.com
省略
;; Query time: 22 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Tue May 10 10:31:23 2016
;; MSG SIZE rcvd: 103

> UP TO up.qiniu.com <

Upload Error => Post http://up.qiniu.com: EOF

Statistics Time Elapesed: 60114 ms

问题诊断

从诊断信息来看,网络连通性(ping)和云服务器域名解析(dig)都未发现问题。
最终的故障点在Upload的过程。
推测在Upload环节,qwebtest程序生成各种大小的文件,上传到云服务,以测试功能的可用性。
根据这个推测,那问题极有可能在上传的过程,有部分数据包被Drop,导致整个传输最后失败。

解决方案

MTU(Ethernet)默认值为1500

  • 减去PPP报文头尾的开销8Byte
  • 减去TCP/IP报文各占20Bytes。

因此,要维持正常的TCP通讯,TCP MSS=1500-8-20-20=1452。

项目 默认值 建议值
MTU 1500 1492
TCP MSS 1460 1452

为什么默认的默认的1500和1460会出错

在Redhat和CentOS系统下,默认的MTU值为1500,TCP MSS默认值为TCP MSS值为1460.(以下命令可以查看)

在基于PPPoE的TCP通讯中,TCP MSS加上TCP/IP的报文开销[20+20],MTU实际值大于MTU(PPPoE)值1492,路由器丢弃该数据包。

一般的,路由器会发出ICMP报文要求对端服务器重新进行分片传输。某些服务器会因安全问题关闭ICMP报文回应,拒绝接收来自路由器的重传请求,导致部分数据包被丢弃,整个通讯过程失败。

因此,需要路由器在TCP协商过程介入修改MSS值,维持数据包尺寸小于MTU(PPPoE)值,保证正常通讯。

[root@gggitlabapp01p ~]# ip link list
 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
     link/ether 00:50:56:96:17:51 brd ff:ff:ff:ff:ff:ff

 [root@gggitlabapp01p ~]# 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
 16:59:25.589330 IP 192.168.20.253.60293 > 192.168.30.11.http: Flags [S], seq 4035013607, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
 16:59:28.313952 IP 192.168.20.253.60294 > 192.168.30.11.http: Flags [S], seq 406328772, win 8192, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

参考资料

Troubleshooting MTU Size in PPPoE Dialin Connectivity