PHP случайные тайм-ауты cURL при получении 100% тела - PullRequest
0 голосов
/ 11 февраля 2020

У нас есть приложение с ~ 50 фронт-серверами с кодом PHP, которые обеспечивают 15-25 тыс. Запросов в секунду от HTTP до GO серверов API через nginx с тайм-аутом 100 мс с использованием библиотеки guzzle. Время от времени (случайным образом, несколько раз в день) мы видим, что 500-10k RPS не выполняются с ошибкой тайм-аута curl в журналах PHP front-серверов. Все исключения внутри журналов выглядят так:

cURL error 28: Operation timed out after 100 milliseconds with 143 out of 143 bytes received.

Самое интересное, что он всегда получает 100% out of 100% байт, никогда не бывает 100 of 102 или 0 of 70. Таким образом, PHP получает полное тело (мы уверены в этом, потому что когда мы воспроизводим эти запросы с помощью CLI curl, его размер всегда равен размеру тела с ошибочным ответом).

Когда мы начинаем отслеживать эти тайм-ауты запросы внутри журналов доступа nginx показывают, что каждый из этих запросов успешно обрабатывается вышестоящими службами (Go API) в течение 1 мс (в среднем) и возвращается nginx без каких-либо задержек. Nginx журналы доступа:

GET [path] HTTP/1.1" 200 228 "-" [...] request_time: 0.001 upstream_addr: [addr] upstream_response_time: 0.001 upstream_status: 200

  • nginx настроен на максимальное количество клиентов (миллионы соединений), как я говорил с нашими разработчиками;
  • 99-й процентиль времени ответа в Go службе <1 мс; </li>

В чем может быть проблема времени ожидания 100 мс и куда копать, чтобы ее решить?

UPD:

NGINX конфигурация, связанная с клиентскими подключениями:

worker_processes        32;
worker_rlimit_nofile    65535;

events {
    worker_connections      32767;
    accept_mutex on;
}

upstream [service] {
    server [main] max_fails=0;
    server [...] backup max_fails=0;
    keepalive 16;
}

location ^~ /[path]/ {
    proxy_pass http://[service]/;
    proxy_http_version 1.1;

    keepalive_timeout 30;
    keepalive_requests 500;

    reset_timedout_connection on;

    proxy_set_header Connection "";
}

GO версия 1.13. net/http используется для обслуживания клиентов. Сервис не имеет внешних зависимостей (базы данных, кеш и т. Д. c.), Он просто вычисляет га sh для входящего запроса на основе входных данных.

PHP версия 7.2.0 использует guzzlehttp/guzzle@5.3.4 HTTP-клиент

1 Ответ

0 голосов
/ 11 февраля 2020

На вашем Балансировщике нагрузки вы должны принудительно закрыть соединение, когда запрос завершен sh

backend nodes
  ...
  option forceclose
  ...

При этом балансировщик нагрузки закроет соединение, когда увидит ответ, переданный

https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#option% 20forceclose

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...