Перейти к содержимому

Запрос к внешнему сервису не проходит - разбор причин

Код обращается к чужому сервису, а ответа нет или приходит ошибка. Разбираем причины по убыванию частоты, начиная с проверки доступа наружу.

С чего начать

Проверяем доступ наружу с самого сервера:

Окно терминала
curl -sS -o /dev/null -w '%{http_code} %{time_total}s\n' https://api.example.com/ping
# запрос с машины разработчика ничего не доказывает: проверяем с боевого сервера

Проверка с сервера отделяет проблему сети от проблемы кода. Половина разборов заканчивается здесь: исходящие соединения закрыты, и никакой код этого не обойдёт.

Смотрим, что именно возвращает клиент платформы:

$http = new \Bitrix\Main\Web\HttpClient(['socketTimeout' => 5, 'streamTimeout' => 10]);
$body = $http->get('https://api.example.com/ping');
printf("код=%s ошибки=%s\n", $http->getStatus(), print_r($http->getError(), true));
// пустой ответ с кодом ноль означает, что до сервиса вообще не достучались

Проверяем сертификат и его цепочку:

Окно терминала
curl -sSv https://api.example.com/ping 2>&1 | grep -iE 'ssl|certificate' | head
# устаревшие корневые сертификаты на сервере ломают соединение целиком

Смотрим ответ сервиса при отказе:

printf("статус=%s\n", $http->getStatus());
print_r($http->getHeaders()->toArray());
echo mb_substr($body, 0, 500); // текст ошибки сервис почти всегда пишет в теле

Считаем частоту своих запросов:

Окно терминала
grep -c 'api.example.com' /home/bitrix/www/local/logs/http.log
# лимит запросов у сервиса считается за минуту или за сутки, и его легко превысить

Причины

  1. Закрыт исходящий доступ с сервера примерно 30% случаев

    ПризнакЗапрос висит до предела ожидания, ответа и кода состояния нет вовсе.

    ПроверкаПробуем достучаться до сервиса консольным клиентом прямо с боевого сервера.

    Что делатьОткрываем исходящие соединения к нужному адресу и порту вместе с администратором.

  2. Проблема с сертификатом соединения примерно 20% случаев

    ПризнакСоединение обрывается с сообщением о проверке подлинности сертификата.

    ПроверкаСмотрим подробный вывод консольного клиента и дату корневых сертификатов сервера.

    Что делатьОбновляем набор корневых сертификатов: проверку подлинности при этом не отключаем.

  3. Неверный или просроченный токен примерно 20% случаев

    ПризнакСервис отвечает быстро и коротко: доступ запрещён или требуется авторизация.

    ПроверкаПечатаем статус ответа и первые строки тела: причина обычно написана словами.

    Что делатьВыпускаем новый токен и переносим его в настройки: в коде и в репозитории ему не место.

  4. Превышен лимит запросов сервиса примерно 15% случаев

    ПризнакЧасть запросов проходит, часть отклоняется, и всё зависит от времени суток.

    ПроверкаСчитаем свои запросы к сервису по журналу за минуту и за сутки.

    Что делатьСтавим кэш ответов и очередь: лимит снимается не уговорами, а сокращением обращений.

  5. Сервер отличается от машины разработчика примерно 10% случаев

    ПризнакНа стенде запрос проходит, на боевом сервере тот же код не работает.

    ПроверкаСравниваем версию языка, набор расширений и настройки прокси на обеих машинах.

    Что делатьПриводим окружения к одному виду и указываем прокси в настройках клиента явно.

  6. Сервис блокирует адрес сервера примерно 5% случаев

    ПризнакС сервера ответа нет совсем, а с другой машины тот же запрос проходит.

    ПроверкаПроверяем запрос с другого адреса и уточняем у сервиса, нет ли блокировки.

    Что делатьПросим внести адрес в белый список сервиса либо выпускаем запросы через разрешённый узел.

Частые вопросы

Почему нельзя отключить проверку сертификата?

Это открывает соединение для подмены ответа посредником. Проблему решают обновлением корневых сертификатов на сервере, а не отключением проверки.

Что делать, если сервис отвечает медленно?

Ставить короткие таймауты и выносить вызов в фон или в очередь. Ожидание чужого сервиса в запросе посетителя недопустимо.

Как понять, что виноват именно лимит?

По коду ответа и тексту в теле: сервисы обычно пишут об этом прямо. Дополнительно помогает счётчик своих запросов по журналу.

Нужно ли повторять неудачный запрос?

Да, две-три попытки с паузой закрывают короткие сбои сети. Бесконечные повторы вредны: они добивают и сервис, и очередь.

Где хранить журнал обращений?

В отдельном файле журнала решения с адресом, кодом ответа и временем. Без него разговор с поддержкой сервиса превращается в спор без доказательств.

Смежное

Первоисточник