PHP/curl: namelookup_time/dns замедляет запросы

РЕДАКТИРОВАТЬ: Найдена часть причины - см. внизу.

Я делаю стандартный вызов curl из php. Однако во время разрешения имени, похоже, происходит зависание. В моем окне OSX namelookup_time постоянно превышает 1 секунду для этого и других запросов к одной и той же подсети. Linux-бокс в моей подсети, выполняющий тот же запрос, имеет 0,02-секундный ответ для другой подсети, так что это проблема с моим ящиком.

Это проблема, так как наше приложение делает много вызовов в эту подсеть для создания страницы, поэтому секунды складываются.

Мой ответ curl_getinfo (ссылка вырезана)

array
  'url' => string ' < SNIPPED > '... (length=1449)
  'content_type' => string 'text/plain; charset=utf-8' (length=25)
  'http_code' => int 200
  'header_size' => int 227
  'request_size' => int 1480
  'filetime' => int -1
  'ssl_verify_result' => int 0
  'redirect_count' => int 0
  'total_time' => float 1.165444
  'namelookup_time' => float 1.001272
  'connect_time' => float 1.017765
  'pretransfer_time' => float 1.017781
  'size_upload' => float 0
  'size_download' => float 92562
  'speed_download' => float 79422
  'speed_upload' => float 0
  'download_content_length' => float 92562
  'upload_content_length' => float 0
  'starttransfer_time' => float 1.043094
  'redirect_time' => float 0
  'certinfo' => 
    array
      empty
  'redirect_url' => string '' (length=0)

У меня есть подозрение, что задержка поиска имени связана с IPv6, поэтому я попробовал следующее:

1) Следуйте инструкциям здесь, чтобы отключить Ipv6 на OSX, включая перезагрузку. Я установил для всех экземпляров IPv6 значение INACTIVE, как предлагается в статье.

http://community.centrify.com/t5/Express-for-Mac-Tips-and-Tricks/Использование-локальных-доменов-с-Centrify-Directcontrol-on-the-Mac/ba-p/3724

Я подтвердил, что мой Mac не поддерживает IPv6, здесь: http://ipv6test.google.com/.

2) Пересобрал PHP с --disable-ipv6.

php -i показывает: поддержка IPv6 => отключена

хотя в разделе curl написано «IPv6 => Yes», ​​и я не знаю, как хирургическим путем отключить это.

3) Запустите это перед вызовом curl:

curl_setopt($c, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

К сожалению, ни один из вышеперечисленных шагов не сработал - я все еще получаю время разрешения имен более 1 секунды. Есть ли у кого-нибудь предложения по устранению неполадок или, что еще лучше, волшебная пуля? :)

(Примечание. Я гуглил и задавал этот вопрос, но безрезультатно..)

Редактировать: отвечая на вопросы ckhan ниже:
1) Я получаю ту же 1 секунду + namelookup_time, используя IP-адрес или полное доменное имя:

'url' => string 'HTTP://172.19.105.171:8070  <SNIPPED> '... (length=1439)
...
'namelookup_time' => float 1.001309

2) У клиента командной строки нет такой проблемы:

# url.txt has the same url as the above curl call
time cat url.txt |xargs curl
<... response output ...>
real  0m0.053s
user  0m0.009s
sys 0m0.008s

3) у dig вроде нет проблем с доступом к серверу.

dig 172.19.105.171
...
;; Query time: 77 msec
...

Моя среда:
PHP 5.3.8
OSX 10.7.3

Частичное решение

Код приложения использует curl_multi_select, время ожидания по умолчанию которого составляет 1 секунду. Изменение этой задержки на 0,00005 секунды значительно ускоряет возврат вызова. Так вот что вызывает задержку. Тем не менее, я еще не знаю, почему это отличается от Linux и OSX или от конкретного варианта php/libcurl, который я создал (5.3.8).


person vaughnkoch    schedule 24.05.2012    source источник
comment
3 вопроса: 1) Вы проверили, что использование IP-адреса вместо имени быстро? 2) Можете ли вы вывести PHP из цикла и подтвердить, что просто использование клиента командной строки curl имеет ту же проблему? 3) можете ли вы вывести curl из цикла и подтвердить, что nslookup/dig работают медленно?   -  person ckhan    schedule 24.05.2012
comment
Я бы запустил traceroute и сравнил с быстрой Linux-системой — они действительно в одной подсети, верно?   -  person ckhan    schedule 24.05.2012
comment
Хорошая мысль. Я сравнивал их ранее, время трассировки было сопоставимо (15-30 мс), но не более 1 секунды.   -  person vaughnkoch    schedule 24.05.2012
comment
Проверьте время пинга, и если оно сравнимо, то вернитесь к пункту 2 — это все сетевое или только PHP?   -  person ckhan    schedule 24.05.2012
comment
Время пинга сопоставимо - 3 мс на Linux и 15 мс на моем OSX (хотя сейчас я подключен к VPN, у меня те же проблемы в офисе). Поскольку время dig, ping и curl командной строки в порядке, похоже, это связано с PHP/libcurl, но я пока не могу определить, что именно.   -  person vaughnkoch    schedule 24.05.2012
comment
Если статистика по-прежнему указывает на то, что время будет искать имя даже при использовании IP-адреса, я думаю, что лучше всего выполнить трассировку wireshark.   -  person ckhan    schedule 24.05.2012
comment
Также можно использовать dtruss и получать относительные временные метки для системных вызовов. Просто просматриваю источники завитков сейчас ... вы не используете прокси, не так ли?   -  person ckhan    schedule 24.05.2012


Ответы (2)


Код приложения PHP использует curl_multi_select, время ожидания по умолчанию которого составляет 1 секунду. Изменение этой задержки на 0,00005 секунды значительно ускоряет возврат вызова. Так вот что вызывает задержку. Тем не менее, я еще не знаю, почему это отличается от Linux и OSX или от конкретного варианта php/libcurl, который я создал (5.3.8).

Я собираюсь открыть другой вопрос SO, чтобы попытаться решить проблему curl_multi_select.

person vaughnkoch    schedule 25.05.2012
comment
Новый вопрос: stackoverflow.com/questions/10747626/ - person vaughnkoch; 25.05.2012

Вы можете исправить свой домен в /etc/hosts, тогда php curl не нужно искать DNS, чтобы найти IP-адрес. Это сработало для меня.

person Nguyễn Văn Toàn    schedule 08.04.2019