curlと127.0.0.1とlocalhost
curlでレスポンスタイムを取得して、その値を監視していたのだけど
ホストの指定を「127.0.0.1」にするか「localhost」にするかで結果がだいぶ違う。
どのくらい違うかというとこのくらい。
$ curl -skL -o /dev/null -w "%{time_total}\n" http://127.0.0.1/test.html
0.001
$ curl -skL -o /dev/null -w "%{time_total}\n" http://localhost/test.html
0.152
ちなみにDigitalOceanのCentOS 7です。
$ uname -a
Linux web01 3.10.0-123.8.1.el7.x86_64 #1 SMP Mon Sep 22 19:06:58 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ curl -V
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.15.4 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz
$
どこが遅いか
こちらのサイトを参考にさせてもらって、どこが遅いのか調べてみます。
curlでボトルネック調査をする
http://d.hatena.ne.jp/akuwano/20120503/1335994486
curl 7.29.0で、127.0.0.1の場合
$ curl -o /dev/null 'http://127.0.0.1/test.html' -w @/tmp/curl_env.txt -s
url_effective : http://127.0.0.1/test.html
http_code : 200
http_connect : 000
time_total : 0.001
time_namelookup : 0.000
time_connect : 0.000
time_appconnect : 0.000
time_pretransfer : 0.000
time_redirect : 0.000
time_starttransfer : 0.001
size_download : 48894
size_upload : 0
size_header : 240
size_request : 82
speed_download : 44815765.000
speed_upload : 0.000
$
curl 7.29.0で、localhostの場合
$ curl -o /dev/null 'http://localhost/test.html' -w @/tmp/curl_env.txt -s
url_effective : http://localhost/test.html
http_code : 200
http_connect : 000
time_total : 0.152
time_namelookup : 0.151
time_connect : 0.151
time_appconnect : 0.000
time_pretransfer : 0.151
time_redirect : 0.000
time_starttransfer : 0.152
size_download : 48894
size_upload : 0
size_header : 240
size_request : 82
speed_download : 322339.000
speed_upload : 0.000
$
localhostの場合150msくらい遅いです。もう答えっぽいのが見えてますけど、気にしない。
straceしてみる
遅いケースを、straceで追いかけてみます。
strace -tt -s 1024 curl -skL http://localhost/test.html > /dev/null
とかすると、
poll(0, 0, 150) = 0 (Timeout)
なんか怪しいのがでてます。150だし。
で、このままググるとすぐに答えが出てきちゃうんだけど、ここにたどり着きました。
Bug 1130239 - Difference in curl performance between RHEL6 and RHEL7
https://bugzilla.redhat.com/show_bug.cgi?id=1130239
要するにlibcurlのバグってことですかね。
新しいcurlでやってみる
http://curl.haxx.se/download.html
から新しそうなやつをダウンロードしてコンパイルします。
オプションを間違えたのでインストールパスがビンビンですが気にしない。
$ /usr/local/bin/bin/curl -V
curl 7.46.0 (x86_64-pc-linux-gnu) libcurl/7.46.0
Protocols: dict file ftp gopher http imap pop3 rtsp smtp telnet tftp
Features: IPv6 Largefile UnixSockets
$
curl 7.46.0で、127.0.0.1の場合
$ /usr/local/bin/bin/curl -o /dev/null 'http://127.0.0.1/test.html' -w @/tmp/curl_env.txt -s
url_effective : http://127.0.0.1/test.html
http_code : 200
http_connect : 000
time_total : 0.001
time_namelookup : 0.000
time_connect : 0.000
time_appconnect : 0.000
time_pretransfer : 0.001
time_redirect : 0.000
time_starttransfer : 0.001
size_download : 48894
size_upload : 0
size_header : 240
size_request : 82
speed_download : 40677204.000
speed_upload : 0.000
$
curl 7.46.0で、localhostの場合
$ /usr/local/bin/bin/curl -o /dev/null 'http://localhost/test.html' -w @/tmp/curl_env.txt -s
url_effective : http://localhost/test.html
http_code : 200
http_connect : 000
time_total : 0.001
time_namelookup : 0.001
time_connect : 0.001
time_appconnect : 0.000
time_pretransfer : 0.001
time_redirect : 0.000
time_starttransfer : 0.001
size_download : 48894
size_upload : 0
size_header : 240
size_request : 82
speed_download : 34505292.000
speed_upload : 0.000
$
同じくらいになったのでよしとする。
おまけ
こういう時、127.0.0.1 と 127.1 と 0 は等価かと思ったけど、結果はこうなった。ややこしい。
(curl 7.29.0)
$ curl -skL -o /dev/null -w "%{time_total}\n" http://127.0.0.1/test.html
0.001
$ curl -skL -o /dev/null -w "%{time_total}\n" http://127.1/test.html
0.151
$ curl -skL -o /dev/null -w "%{time_total}\n" http://0/test.html
0.152
$