2013-07-23 6 views
5

Sono in esecuzione di PHP su una macchina virtuale CentOS sotto MacOS X e qualsiasi richiesta cURL prende costantemente 15s a correre:PHP CURL costantemente prendendo 15s per risolvere 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 

Tuttavia, gethostbyname() è molto veloce:

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

E, ping risolve il nome quasi istantaneamente.

Per impostazione predefinita, /etc/resolv.conf aveva solo nameserver 192.168.1.1 in esso, quindi l'ho cambiato di utilizzare i server DNS di Google:

nameserver 8.8.8.8 
nameserver 8.8.4.4 

ma senza fortuna. Qualche suggerimento?


Update 1: le seguenti correzioni del problema:

curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 

Quindi, per quanto mi risulta, si sta cercando di risolvere sia IPv4 che IPv6, e la risoluzione IPv6 viene a mancare, dopo un timeout di 15s.

Questo a causa di una configurazione errata sulla macchina 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

Quanto tempo ci vuole se lo fai 'curl_init ('https://66.220.152.19');' –

+0

Puoi fare una cattura di pacchetti e confermare che cURL sta segnalando questo correttamente? – Barmar

+0

@Alex L'ho provato con l'indirizzo IP, ed è molto veloce. Sicuramente un problema DNS, come evidenziato da 'CURLINFO_NAMELOOKUP_TIME'. – Benjamin

risposta

13

Il problema era una ricerca IPv6 in mancanza sulla mia macchina. La soluzione:

Cambiato /etc/resolv.conf a:

nameserver 8.8.8.8 
nameserver 8.8.4.4 

Dopo il riavvio, resolv.conf preso sovrascritti, quindi l'aggiunta di questa linea di /etc/sysconfig/network-scripts/ifcfg-eth0 (che stava usando BOOTPROTO=dhcp) ha risolto il problema:

PEERDNS=no 

E tutto ora funziona come un fascino.

In alternativa, se si verifica questo problema su un server su cui non è possibile modificare la configurazione, configurare cURL in questo modo:

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

Ci può essere qualcosa che non va nel vostro sistema, ma trovo un modo di aggirarlo.

$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/Il problema del DNS era a livello di macchina, quindi l'uso di 'gethostbyname()' non è d'aiuto; 2/la sostituzione dell'host con l'IP è molto probabilmente destinata a fallire, poiché la maggior parte dei siti Web oggi utilizza host virtuali basati sui nomi; 3/Ho già trovato la ragione del mio problema, l'ho spiegato sopra e pubblicato la soluzione; non sai qual è il tuo motivo ..? Senza offesa, ma ... ;-) – Benjamin

+0

@ Benjamin Sì hai ragione. Anche se funziona da parte mia, ma non è un modo corretto. 1/il gethostbyname() funziona da parte mia perché il mio problema DNS è causato dal curl del PHP. 2/come dici tu, la maggior parte dei siti Web oggi utilizza host virtuali basati sui nomi, quindi non funzionerà sulla maggior parte dei siti web. – schumyxp