Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

起因:

我们的程序需要从文件服务器拉去文件(跨机房),
程序运行的机器有电信、联通、移动3线,3个IP 假定为
01_DX_IP, 01_LT_IP, 01_YD_IP
文件服务器也是电信、联通、移动3线,3个IP
02_DX_IP, 02_LT_IP, 02_YD_IP
其域名为myfile.com

使用wget拉去文件,为了保证出口带宽用的尽量上,绑定出口IP

wget  --bind-address=01_YD_IP  -t 3 -T 120  --limit-rate=3M -S -O 1407856770354_858932.mp4 http://myfile.com/data10/sony/303/2014-08/12/1407856770354_858932.mp4

按照预先的想法,绑定了移动IP,正常DNS服务器会返回一个文件服务器的移动IP,速度应该不会太慢,事情情况下,下载速度不到100k

1. 排查:

1.1 观察文件下载连接

观察wget打印的日志,显示实际建立连接访问的是联通的IP

Resolving myfile.com... 02_LT_IP,  ...
Connecting to myfile.com|02_LT_IP|:80... connected.
HTTP request sent, awaiting response... ^C

使用lsof观察进程的连接情况

[xxx@c3n~]$ sudo lsof -p  133396
COMMAND    PID USER   FD   TYPE     DEVICE    SIZE/OFF        NODE NAME
wget    133396 root  cwd    DIR        8,2        4096      
59640871425 /datapool/log/inject/xxx.log
wget    133396 root    6w   REG       0,17   164815000 59756490241 /datapool/injectBase/1408203875738_777462.mp4
wget    133396 root    7u  IPv4 1479434406         0t0         TCP 01_YD_IP:29657->02_LT_IP:http (ESTABLISHED)

注意这一行 TCP 01_YD_IP:29657->02_LT_IP:http (ESTABLISHED)
本地的bind address确实已经生效,已经绑定了移动IP, 但是文件服务器的IP地址却是联通IP, 那只能是DNS解析有问题了

1.2 追踪DNS解析

wget 增加 -d 参数, 可以查看wget的细节

Setting --bind-address (bindaddress) to 01_YD_IP
Setting --tries (tries) to 3
Setting --timeout (timeout) to 120
Setting --limit-rate (limitrate) to 3M
Setting --server-response (serverresponse) to 1
Setting --output-document (outputdocument) to 1407856770354_858932.mp4
DEBUG output created by Wget 1.12 on linux-gnu.

--2017-07-11 11:08:37--  http://myfile.com/data10/sony/303/2014-08/12/1407856770354_858932.mp4
Resolving myfile.com... 02_LT_IP, ...
Caching myfile.com => 02_LT_IP
Connecting to myfile.com|02_LT_IP|:80... Releasing 0x0000000002618870 (new refcount 0).
Deleting unused 0x0000000002618870.
connected.
Created socket 4.
Releasing 0x0000000002618580 (new refcount 1).

---request begin---
GET /data10/sony/303/2014-08/12/1407856770354_858932.mp4 HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: xxxxx
Connection: Keep-Alive

---request end---
HTTP request sent, awaiting response... ^C

可以看出wget 先进行DNS解析,然后实际与文件服务器建立连接,下载文件

对53端口,观察程序与DNS服务器的通讯

[xxx@c3n]# tcpdump port 53 -i p3p1
11:14:34.187939 IP 01_LT_IP.22683 > pdns.dnspod.cn.domain: 47926+ A? myfile.com. (50)
11:14:34.217628 IP pdns.dnspod.cn.domain > 01_LT_IP.22683: 38811 5/0/0 A 02_LT_IP (130)

这里可以看到请求DNS服务的出口IP是一个联通IP01_LT_IP,怪不得DNS服务器解析myfile.com -> 02_LT_IP

1.3 小结

到此问题,很清楚wget下载文件有2个步骤
1. 请求DNS服务器获取文件服务器IP地址
2. 与文件服务器连接,下载文件
在步骤1中,并没有bind IP,导致DNS解析的线路错误。而不同运营商直接的交汇的出口比较窄,所以下载速度就上不去了

2. 解决

这明显是wget工具的问题,尝试查看资料,看看新版的wget有没有解决这个问题
自v1.18 以后 新增2个参数,此参数用于绑定请求DNS服务器时的出口IP

‘--bind-dns-address=ADDRESS’
[libcares only] This address overrides the route for DNS requests. If you ever need to circumvent the standard settings from /etc/resolv.conf, this option together with ‘--dns-servers’ is your friend. ADDRESS must be specified either as IPv4 or IPv6 address. Wget needs to be built with libcares for this option to be available.

需要自己重新编译wget, 编译时,需要libcares

./configure --with-cares

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注