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