2013-07-23 3 views
5

Я бегу PHP на виртуальной машине CentOS под MacOS Х, и любой запрос Curl последовательно принимает 15s запустить:PHP Curl последовательно принимает 15s разрешить DNS

$c = curl_init('https://graph.facebook.com'); 
curl_exec($c); // takes 15s to return... 
echo curl_getinfo($c, CURLINFO_NAMELOOKUP_TIME); // 15.01 seconds 

Однако gethostbyname() очень быстро:

echo gethostbyname('graph.facebook.com'); // almost instant 

И, ping решает имя почти сразу же.

По умолчанию /etc/resolv.conf был только nameserver 192.168.1.1 в нем, так что я изменил его использовать DNS-серверы Google:

nameserver 8.8.8.8 
nameserver 8.8.4.4 

Но не повезло. Любые намеки?


Update 1: следующие исправления проблемы:

curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 

Так, насколько я понимаю, он пытается решить как IPv4, так и IPv6, и разрешение IPv6 терпит неудачу, после тайм-аута 15 с.

Это из-за неправильной конфигурации на машине Linux?


Update 2:

dig graph.facebook.com aaaa 

;; reply from unexpected source: 10.0.2.2#53, expected 192.168.1.1#53 
;; reply from unexpected source: 10.0.2.2#60944, expected 192.168.1.1#53 
;; reply from unexpected source: 10.0.2.2#53, expected 192.168.1.1#53 

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.4 <<>> graph.facebook.com aaaa 
;; global options: +cmd 
;; connection timed out; no servers could be reached 
+0

Сколько времени это займет, если вы 'curl_init («https://66.220.152.19»);' –

+0

Вы можете сделать захват пакетов и убедитесь, что завиток правильно сообщать об этом? – Barmar

+0

@Alex Я пробовал его с IP-адресом, и это очень быстро. Определенно проблема DNS, как подчеркнуто 'CURLINFO_NAMELOOKUP_TIME'. – Benjamin

ответ

13

Проблема был поиск IPv6 неудачу на моей машине. Решение:

Изменено /etc/resolv.conf на:

nameserver 8.8.8.8 
nameserver 8.8.4.4 

После перезагрузки resolv.conf получил перезаписаны, так что добавление этой строки в /etc/sysconfig/network-scripts/ifcfg-eth0 (который использует BOOTPROTO=dhcp) устранило проблему:

PEERDNS=no 

И всё теперь работает как шарм.

В качестве альтернативы, если эта проблема возникает на сервере, на котором вы не можете изменить конфигурацию, настроить Curl таким образом:

curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 
-2

Там может быть что-то не так в вашей системе, но я нахожу способ обойти его.

$urldata = parse_url($yourUrl); 
$host = $urldata['host']; 
$ip = gethostbyname($host); 
$new_Url_dns_resolved = str_replace($host,$ip,$yourUrl); 
//call the dns resolved url instead of the original url 
$c = curl_init($new_Url_dns_resolved); 
+0

Erm ... 1/Проблема DNS была машинной, поэтому использование 'gethostbyname()' не поможет; 2/замена хоста на IP, скорее всего, обречена на провал, так как сегодня большинство веб-сайтов используют виртуальные хосты на основе имени; 3/Я уже нашел причину своей проблемы, объяснил ее выше и разместил решение; не знаете, каков ваш мотив ...? Не обижайтесь, но ... ;-) – Benjamin

+0

@Benjamin Да, вы правы. Хотя это работает с моей стороны, но это не правильный путь. 1/gethostbyname() работает на моей стороне, потому что моя проблема DNS вызвана завихрением PHP. 2/как вы говорите, большинство веб-сайтов сегодня используют виртуальные хосты на основе имени, поэтому они не будут работать на большинстве веб-сайтов. – schumyxp