keepalive

Maxim Dounin mdounin на mdounin.ru
Ср Авг 31 14:41:34 UTC 2011


Hello!

On Wed, Aug 31, 2011 at 05:29:16PM +0400, Evgeny Turnaev wrote:

> Добрый день.
>   Суть вопроса:
> 
>   1) Как себя поведет nginx в режиме keepalive проксирования на бэкенды когда
>   количество соединений превысит максимально заданное конфигом.
>   2) Каким параметром конфига регламетируется максимальное число keepalive
>      соединений к бэкендам ?

Директива keepalive задаёт максимальное количество соединений, 
которое каждый рабочий процесс nginx'а хранит в кеше если 
соединения не заняты обслуживанием запросов.  Если "на сохранение" 
поступает больше соединений - самые старые закрываются.

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

> ---------
> Более подробно:
> Я скомпилил nginx 1.1.1 с этими патчами:
> http://mailman.nginx.org/pipermail/nginx-devel/2011-July/001057.html
> http://forum.nginx.org/read.php?29,213388
> 
> Конфиг:
> upstream uwsgi_ip {
>     ip_hash;
>     server 127.0.0.1:6000;
>     keepalive 1;
> }
> 
> location /uwsgi_ip {
>      uwsgi_pass uwsgi_ip;
>      uwsgi_buffering off;
>      ...
> }
> 
>   Сценарий:
>   Допустим nginx сконфигурирован таким образом что может поддерживать
> 10 keepalive сокетов к бэкенду
>   uwsgi.

Протокол uwsgi не подерживает keepalive, так что включать keepalive для 
uwsgi бекендов бессмысленно.

Кроме того, чтобы хранилось 10 соединений, нужно сказать не 
"keepalive 1;", а "keepalive 10;".

>   При этом бэкенд обрабатывает каждый запрос достаточно долго
> (допустим 15 секунд).
>   Поступило одновременно 10 запросов..
>   Поступление зальнейших запросов на nginx вызовет закрытие самых
> старых сокетов невзирая на то что бэкенд не успел завершить ответ?

Нет.  Будет открыто столько соединений, сколько нужно, чтобы 
обслужить все одновременные запросы.  После завершения всех 
запросов - в кеше останутся 10 соединений (и будут использованы 
для обслуживания вновь поступающих запросов).

Отдельно замечу:

Следует иметь ввиду, что если суммарное число сохраняемых 
соединений во всех рабочих процессах будет больше, чем способен 
обслуживать бекенд, вероятны проблемы по следующему сценарию:

Пусть бекенд способен обслужить 10 соединений и у нас 1 рабочий 
процесс nginx'а с keepalive 10.  

1. Приходит 15 запросов.  При этом nginx попытается открыть 15 
соединений к бекенду, 10 из них бекенд примет, остальные 5 
останутся висеть в listen queue бекенда.

2. Бекенд обслуживает 10 принятных запросов, после чего эти 10 
соединений сохраняются в кеше.  Бекенд по прежнему не способен 
принять ни одного нового соединения, а 5 "невезучих" по прежнему 
висят в listen queue бекенда.

В результате, если бекенд не закроет закешированные соединения, 5 
"невезучих" запросов обслужены не будут и получат 504.

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

Собственно, эта проблема ни разу не нова, практически то 
же самое можно легко наблюдать на обычном process-based сервере 
(e.g. Apache), выставленном в сеть.  Но пользование nginx'а 
расхолаживает.  ;)

Maxim Dounin



Подробная информация о списке рассылки nginx-ru