Re: upstream fastcgi keepalive. Таинственные 40мс
Maxim Dounin
mdounin на mdounin.ru
Пт Сен 4 15:38:55 UTC 2020
Hello!
On Fri, Sep 04, 2020 at 01:33:18PM +0300, Panichev Oleg wrote:
> При включении keepalive в секции upstream для fastcgi серверов
> upstream_response_time увеличивается на 40мс при нагрузке. Это
> достаточно четкий шаг,
> реальный ответ бэкендову нас - единицы миллисекунд, но nginx
> показывает на 40мс больше. Apache benchmark tool показывает
> тоже самое.
>
> С чем связана именно такая задержка? Изменения таймаутов,
> количества реквестов на эти 40мс не влияют, в логе всегда либо
> единицы миллисекунд (время ответа
> для простых соединений, без включения keepalive), либо сразу
> 40мс+время простого запроса. Есть ли способ измерять реальное
> время ответа от бэкенда при
> использовании keepalive?
Смотрите tcpdump между nginx'ом и бэкендом, возможно станет
понятнее, что происходит. Возможные направления, куда, как мне
кажется, имеет смысл копать:
1. Keepalive в случае FastCGI означает, что nginx'у надо
дожидаться не просто закрытия stdout-потока, но и записи
FCGI_END_REQUEST. Если вдруг бэкенд её посылает с задержкой - это
может быть причиной.
2. FastCGI - сложный протокол, и бэкенд может наступать на
классическую проблему delayed ack vs. Nagle. Ну и это хорошо
сочетается с предыдущим пунктом, скажем - если запись
FCGI_END_REQUEST бэкенд шлёт отдельной записью в сокет, то реально
отправится она только по получению ack'а на предыдущую запись, а
тот в свою очередь придёт только по истечению таймаута delayed
ack. Обычно для тестов проще всего отключить delayed ack
глобально на машине, и посмотреть, не починится ли. Лечить
правильно - либо грамотной работой с сокетами (не допускать
паттерна write+write+read), либо выставлением на сокет
TCP_NODELAY.
Ну и да, гугл подсказывает, что 40ms - задержка delayed ack
по умолчанию на линуксе, так что скорее всего оно.
--
Maxim Dounin
http://mdounin.ru/
Подробная информация о списке рассылки nginx-ru