Если функция cURL наотрез отказывалась работать быстрее, чем за 4 секунды, то возможная проблема может находиться в резолве DNS и включившемся IPv6. А для исправления этой проблемы надо чуть-чуть покопаться в сервере.
Неверные DNS серверы
Функция cURL может надолго подвисать из-за неправильно указанных DNS серверов в ОС. Это может приводить к медленной работе сайтов, к примеру, к длительной загрузке некоторых страниц панели администрирования WordPress. В панели администрирования этой CMS может запрашиваться несколько раз подряд информация с api.wordpress.org. К примеру, это происходит на странице "Настройки"-"Общее". Там подгружаются языковые файлы с сервера api.wordpress.org. Если функция cURL отрабатывает дольше, чем за 3 секунды, то на этой странице постоянно возникает ошибка:
WP_Error Object ( [errors] => Array ( [http_request_failed] => Array ( [0] => cURL error 28: Resolving timed out after 3000 milliseconds ) ) [error_data] => Array ( ) )
В этом случае стоит проверить прописанные в системе DNS сервера. Если сервер работает на CentOS 7, то файл настроек DNS находится по адресу:
sudo vi /etc/resolv.conf
В этом файле записаны ip адресов DNS серверов:
nameserver X.X.X.X
nameserver Y.Y.Y.Y
nameserver Z.Z.Z.Z
В этом файле должны содержаться ip адреса DNS серверов (вместо X.X.X.X, Y.Y.Y.Y, Z.Z.Z.Z). Эти адреса можно уточнить у хостинг-провайдера или у дита-центра, в котором размещается сервер. Если указать неверные адреса, то будет появляться задержка при использовании cURL в PHP и даже при использовании консольной команды wget.
Нужно отключить IPv6
После исправления DNS стоит обратить внимание на настройки сети, используя команду ifconfig. Если в проекте не используется IPv6, то стоит отключить его, иначе через него функция cURL тоже будет пытаться резолвить адрес запрашиваемого ресурса. К сожалению, ip адреса шестой версии в России распространены сейчас всего на 4%, поэтому может быть проблема с cURL. Поэтому стоит отключить IPv6 в системе, если он не используется в проекте. Для этого необходимо открыть файл конфигурации:
sudo vi /etc/sysctl.conf
И дописать в конец:
# IPv6 disabled
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
После чего сохранить файл и перезапустить службу:
sudo sysctl -p
Теперь проверим настройки, чтобы убедился что всё применилось. Введём следующие команды и получим ответы:
$ sysctl net.ipv6.conf.all.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 1$ sysctl net.ipv6.conf.default.disable_ipv6
net.ipv6.conf.default.disable_ipv6 = 1$ sysctl net.ipv6.conf.lo.disable_ipv6
net.ipv6.conf.lo.disable_ipv6 = 1
Если на всех запросах вернулось "= 1", то это означает, что для ядра ОС прописаны параметры, которые не позволяют использовать протокол IPv6. Что и было нужно.
Спасибо друг) излазил весь инет - один нормальный человек написал что и как сделать!
Не все сервисы адекватно воспринимают эти настройки для отключения IPv6. Поэтому лучше указывать ещё и внешний интерфейс в файле /etc/sysctl.conf. К примеру, если его название eth0, то будет так:
# IPv6 disabled
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
Иначе сервис systemd-sysctl полезет в файл /proc/sys/net/bridge/bridge-nf-call-ip6tables и ещё много чего. Лучше для верности именно прописывать правило для интерфейса, а не только all и default