Re: HTTP проксирование 1.1

Maxim Dounin mdounin at mdounin.ru
Thu Mar 20 15:00:30 UTC 2014


Hello!

On Thu, Mar 20, 2014 at 02:38:58PM +0000, Anatoly Mikhailov wrote:

> 
> On 20 Mar 2014, at 13:32, Maxim Dounin <mdounin at mdounin.ru> wrote:
> 
> > Hello!
> > 
> > On Thu, Mar 20, 2014 at 12:03:23PM +0000, Anatoly Mikhailov wrote:
> > 
> >> 
> >> On 19 Mar 2014, at 13:37, Maxim Dounin <mdounin at mdounin.ru> wrote:
> >> 
> >>> Hello!
> >>> 
> >>> On Wed, Mar 19, 2014 at 10:42:26AM +0000, Anatoly Mikhailov wrote:
> >>> 
> >>>> 
> >>>> On 18 Mar 2014, at 15:10, Maxim Dounin <mdounin at mdounin.ru> wrote:
> > 
> > [...]
> > 
> >>>> супер, переписал конфигурацию для проксирования S3 на upstream, получилось очень классно,
> >>>> вопрос - почему бы не сделать keepalive для бэкэнда по умолчанию?
> >>> 
> >>> Использование постоянных соединений полезно в основном в тех 
> >>> случаях, когда до бекенда - далеко.  В условиях близких бекендов 
> >>> оно обычно не нужно.  Наоборот, в некоторых ситуациях постоянные 
> >>> соединения могут повредить - например, если бекенд сильно ограничен по 
> >>> количеству соединений, которые он может обрабатывать.  В 
> >>> документации даже специально добавлено замечание про это, т.к. 
> >>> люди периодически наступают, cм. http://nginx.org/r/keepalive/ru.
> >>> 
> >>> Так что я к идее сделать keepalive к бекендам поведением по 
> >>> умолчанию - отношусь скептически.
> >>> 
> >> 
> >> Я правильно понимаю, keepalive (в контексте upstream) задает количество
> >> TCP соединений, которые не будут закрываться, даже при отсутствии будущих запросов?
> > 
> > Да.
> > 
> > Следует, однако, учитывать, что это число - на каждый рабочий 
> > процесс.
> > 
> >> Если да, то какой таймаут, такой же как для клиентских TCP подключений, указанных
> >> через директиву keepalive_timeout?
> > 
> > Таймаут определяется тем, сколько соединение будет поддерживать 
> > бекенд.  Сам nginx ничего закрывать не пытается.
> > 
> >> Вопрос второй - если известно, что бэкэнд держит, скажем, 50 соединений, 
> >> то keepalive 50 поможет нам повторно их использовать в будущем, без повторных syn+ack?
> > 
> > Если бекенд держит только 50 соединений, то ставить в конфиге 
> > "keepalive 50" - нецелесообразно, т.к. при таких настройках весь 
> > бекенд может быть занят одним рабочим процессом.
> 
> Все понятно, кроме этого момента. Если keepalive - нижняя граница, то второй рабочий
> процесс откроет больше соединений, чем указано в keepalive... или здесь все по другому?

Рассмотрим такой пример:

- пусть у нас бекенд может обработать до 50 соединений 
  включительно (e.g., он использует модель process-per-connection, 
  и запущено 50 процессов);

- пусть все эти соединения открыл один рабочих процессов nginx'а 
  и держит открытыми, сохранив в кеш (ему сказано кешировать до 50  
  соединений включительно);

И тут другой рабочий процесс nginx'а, у которого в кеше нет 
соединений, вдруг захотел зачем-то сходить на бекенд, и пытается 
открыть соединение к бекенду.

Проблема состоит в том, что наш бекенд - умеет только 50 
соединений, больше - не умеет.  И то 51-е соединение, которое мы 
пытаемся открыть, - обслуживать некому.  Соответственно это 
соединение никто не примет, и случится ошибка.

Чтобы такого не происходило - нужно ограничивать количество 
постоянных соединений.  В RFC2616, например, по этому вопросу 
сказано: "A single-user client SHOULD NOT maintain more than 2 
connections with any server or proxy".  Столь малыми значениями 
сейчас не ограничиваются даже браузеры, но и сильно много 
соединений держать в кеше не нужно.

Совсем простое правило - не следует делать кеш соединений больше, 
чем (N / worker_process) - 1, где N - число соединений, которое 
способен обслуживать бекенд.

-- 
Maxim Dounin
http://nginx.org/



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