Что вызовет checkdnsrr () или dns_get_record (), чтобы занять слишком много времени?

$domain = 'abasdfasdfac.comlkjljkl'; //Yes, an ugly invalid domain

$start_time = microtime(true);
echo "
MX "; var_dump(checkdnsrr($domain, 'MX')); echo "

"; $end_time = microtime(true); echo "
run time: " . ($end_time - $start_time) . "

";

I am getting times in the order of 60 milliseconds when running this on my development system (Win+XAMPP on residential DSL w/AT&T).

Однако при загрузке на живой сервер и оттуда время выполнения переходит в 20 второй .

Результаты совпадают, если вместо этого я использую @dns_get_record ($ domain, DNS_MX) .

What could be causing this? Is is a matter of AT&T's DNS servers returning with a result faster than whatever my production server is pointing to? Still, twenty seconds seems excessive.

Что еще более важно, как это можно исправить?

Я использую это как последний этап проверки подлинности электронной почты. Тем не менее, я не могу заставить пользователя ждать двадцать секунд, пока возвращается DNS-поиск.

<�Сильный> EDIT:

Я изучил это немного дальше. Использование dig из консоли выполняется быстро на том же сервере, который занимает от 20 до 30 секунд, чтобы выполнить проверку DNS на недопустимых доменах. Это может быть важным моментом. Допустимые домены возвращаются с помощью checkdnsrr() или @dns_get_record .

В качестве промежуточной меры я рассматриваю подстановку @dns_get_record в мою проверку действительности электронной почты с помощью функции dig , которую я написал:

// Use "dig" command to get DNS record data
// $type    ANY = Complete record
//          A   = Address Record
//          MX  = Mail Exchange Record
//          CNAME = Canonical Name Record  (http://en.wikipedia.org/wiki/Canonical_name_record)
//
//          more types: http://en.wikipedia.org/wiki/List_of_DNS_record_types
//
// $host    Domain to investigate
//
function dig_get_dns_record($type, $host) 
{ 
    $cleaned_host = escapeshellcmd($host);
    ob_start(); 
       //Note: for this to work on Windows/XAMPP "dig" has to be installed and the search path
        passthru("dig $type $cleaned_host"); 
        $lookup = ob_get_contents(); 
    ob_end_clean(); 
    //echo "
" . $lookup . "
"; //Remove comment to see dig output
    return $lookup; 
}   


// For the purposes of deciding if a domain is real, this checks, the MX, A and CNAME
// and returns FALSE if none are found.  If only one of the three exists we give it
// the benefit of the doubt.
//
// $host    Domain to investigate
//
function has_valid_dns($host)
{
    $result  = dig_get_dns_record("MX", $host);
    $result .= dig_get_dns_record("A", $host);
    $result .= dig_get_dns_record("CNAME", $host);
    return strpos($result, "ANSWER SECTION:") > 0;
}

Хотя это выведет меня из леса, это действительно не ответ. Я уверен, что реальной проблемой является настройка конфигурации на сервере Linux.

Если вы заинтересованы в тестировании задержки, вот страница с несколькими тестами (формы на сайте страдают от этой задержки прямо сейчас - пожалуйста, не связывайтесь с формами, если вы просто не хотите зарегистрироваться):

<�Сильный> EDIT: link removed as it is no longer relevant and page will be deleted

Рекомендации по тестированию:

apple.com
apple.commmmmmmmmmm
example.com
asdfasdfasdf

<�Сильный> NB

Ответ AndreKR заставил меня проверить эти функции с конечным периодом, и это только уменьшило время отклика от десятков секунд до миллисекунд.

Это решило проблему, но на самом деле не отвечало на новый вопрос: почему? Для полноты я, хотя важно добавить эту Nota Bene и ответить на этот вопрос, основываясь на моих исследованиях.

Я вернулся к источнику и прочитал большую часть RFC-1034 и RFC-1035 .

Оказывается, что, что касается DNS, полное доменное имя (FQDN) фактически заканчивается периодом. Большинство ссылок на полное доменное имя не объясняют, что у DNS есть концепция доменных имен absolute и relative . То, как DNS говорит им обособленно, именно с помощью этого периода ожидания.

Если распознаватель DNS видит полное доменное имя DNS-стиля (с периодом ожидания), оно исчезает и находит запрошенные записи для этого полного доменного имени DNS (абсолютная спецификация имени домена). Это может потребовать нескольких попыток. Например, если вы ищете запись MX и которая не существует в записи FQDN, вместо нее может существовать CNAME. DNS-резольвер захватывает CNAME и инициирует новое DNS-запрос, чтобы попытаться найти запись MX.

Что произойдет, если DNS-резольвер обнаружит относительную спецификацию имени домена? Другими словами, что-либо без отстающего периода. Например: «тестирование». Решатель DNS фактически попытается превратить это в абсолютное полное доменное имя, добавив ряд DNS-суффиксов к предоставленному относительному доменному имени. Например:

@dns_get_record("abceabce.gov", DNS_MX); //No trailing period === relative

Если запустить на хосте, скажем, www.example.com , будет генерироваться, по крайней мере, следующий набор запросов:

@dns_get_record("abceabce.gov.www.example.com", DNS_MX);
@dns_get_record("abceabce.gov.example.com", DNS_MX);
@dns_get_record("abceabce.gov.com", DNS_MX);

Каждый из них, скорее всего, терпит неудачу, и весь процесс длится вечно.

Оказывается, весь процесс фактически рассматривается в RFC в проблеме безопасности и предлагаемой коррекции с широко распространенным программным обеспечением DNS . Это стоит прочитать.

9
nl ja de
@ martin's: вы всегда можете отправить сообщение пользователю позже с результатом;) Серьезно, хотя, вероятно, лучше отправить ссылку для проверки электронной почты. Даже если домен действителен, это не значит, что адрес электронной почты или доступ к нему у пользователя.
добавлено автор Wesley Murch, источник
@Michael: Просто закончили тесты. dig возвращает довольно много мгновенно и с надлежащими результатами. Не уверен, куда идти отсюда. Я переустановил PHP на случай, если что-то получится искалеченным. Без изменений. Запуск PHP 5.4.10 на реальном сервере и 5.4.7 на тестовом сервере (XAMPP).
добавлено автор martin's, источник
Вы имеете в виду тестовую страницу или больше общего заявления? Мне нужно сразу сообщить пользователю, если они ввели потенциально недействительный адрес электронной почты, чтобы дать им возможность редактировать его. Например, кто-то может ввести .comm просто по ошибке на подлинной регистрации. Я не вижу, как я мог бы использовать @dns_get_record() в фоновом режиме и по-прежнему обеспечивать хорошую обратную связь, когда он возвращает функцию от 20 до 30 секунд.
добавлено автор martin's, источник
Теперь это было забавно. Благодарю.
добавлено автор martin's, источник
Я бы не делал такого рода жизненно важные сетевые материалы при обработке запроса POST или GET. Лучше всего сохранить что-либо сразу в файле или базе данных, дать пользователю ответ, а затем обработать позже в фоновом режиме.
добавлено автор mvds, источник
Вы пробовали делать dns-lookup за пределами php? С помощью dig ? Это так медленно?
добавлено автор Michael, источник

1 ответы

Очевидно, что функции PHP DNS не имеют таймаута, а время ожидания по умолчанию для dig 5 секунд (с несколькими попытками).

Кроме того, ваш сервер разработки и производства, вероятно, использует разные DNS-серверы для разрешения имен. Теперь некоторые DNS-серверы отправляют пустой ответ на недопустимые домены, а некоторые - djbdns - не посылают никакого ответа вообще ( что прекрасно соответствует спецификации).

Также имейте в виду, что вы должны включить конечный . (точка) в доменное имя, если вы не хотите, чтобы потенциальные поисковые домены из вашей настройки конфигурации resolv.conf/Windows были добавлены, что, вероятно, всегда было бы разрешимым если они имеют подстановочный знак.

10
добавлено
По крайней мере, это, вероятно, выходит за рамки этого вопроса, но я не думаю, что на такой вопрос можно ответить, не зная настройки/вы предоставляете сетевой дамп.
добавлено автор AndreKR, источник
Вау. Вы ударяете его прямо по голове. Я знал об отсутствии таймаута для PHP-функций DNS. На самом деле, ранее сегодня я копался через исходный код PHP, пытаясь понять, что потребуется, чтобы сделать версию с таймаутом. Я не уверен, что вы намеревались это сделать таким образом, но ваше предложение добавить последний период в доменное имя вызвало огромную разницу (см. Тестовую страницу, которую я положил). Даже для нежелательных доменных имен, таких как «abcdabcd», время прошло от 28 секунд до 3 миллисекунд! Теперь я хочу понять, почему. Должен ли я размещать отдельный вопрос только по этой теме?
добавлено автор martin's, источник
Я отредактировал конец моего вопроса, чтобы отразить мои исследования в понимании этой проблемы. Надеюсь, это поможет другим избежать стрижки волос в течение нескольких дней.
добавлено автор martin's, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp