Re: как правильно закрывать соединения при наступлении keepalive_requests: обсудим ?

Илья Шипицин chipitsine на gmail.com
Пн Сен 3 13:20:43 UTC 2018


пн, 3 сент. 2018 г. в 18:15, Maxim Dounin <mdounin на mdounin.ru>:

> Hello!
>
> On Mon, Sep 03, 2018 at 05:43:17PM +0500, Илья Шипицин wrote:
>
> > пн, 3 сент. 2018 г. в 17:30, Maxim Dounin <mdounin на mdounin.ru>:
> >
> > > Hello!
> > >
> > > On Mon, Sep 03, 2018 at 04:45:31PM +0500, Илья Шипицин wrote:
> > >
> > > > пн, 3 сент. 2018 г. в 16:11, Maxim Dounin <mdounin на mdounin.ru>:
> > > >
> > > > > On Sun, Sep 02, 2018 at 11:12:31PM +0500, Илья Шипицин wrote:
> > > > >
> > > > > > есть такое наблюдение. если проксировать на апстрим БЕЗ киэлайв,
> то
> > > на
> > > > > > стороне nginx удивительным образом все хорошо (потому что
> соединение
> > > > > > закрывается по инициативе бекенда)
> > > > > >
> > > > > > если проксировать с включенным кипэлайвом, то в случаях, когда
> > > соединение
> > > > > > закрывается по инициативе nginx, на стороне  nginx порт уходит в
> > > > > > TIME_WAIT.
> > > > > >
> > > > > > с одной стороны - несмертельно. все с этим живут.
> > > > > > с другой стороны - например, в случае, когда запрос последний
> (100-й
> > > при
> > > > > > дефолтном значении keepalive_requests), можно ведь явно добавить
> > > > > > "Connection: Close" ? тем самым помочь бекенду закрыть
> соединение, и
> > > > > > сэкономить один порт на nginx ?
> > > > >
> > > > > Теоретически - можно.
> > > > >
> > > > > Практически - формирование запроса на бэкенд происходит до того,
> > > > > как бэкенд выбран и/или установлено или извлечено из кэша
> > > > > соединение, которое будет использоваться для отправки запроса.
> > > > > Кроме того, один и тот же запрос может быть отправлен на несколько
> > > > > разных бэкендов и/или в несколько разных соединений.
> > > > >
> > > > > Соответственно выставление "Connection: close" по достижении
> > > > > keepalive_requests для конкретного соединения к бэкенду -
> > > > > потребует достаточно серьёзных переделок в логике работы с
> > > > > бэкендами.  Не говоря уже о том, что сейчас при использовании
> > > > > keepalive-соединений заголовок Connection выставляется из конфига
> > > > > через proxy_set_header, и это тоже понадобится переделывать.
> > > >
> > > > да, я про эту магию и говорил. в некоторых случаях можно сделать
> более
> > > умно
> > > >
> > > > > Так что если порты очень жмут - то проще поднять
> > > >
> > > > не жмут. мы научились с этим жить.
> > > > просто в процессе исследований пришла мысль, про которую я и написал.
> > > > было бы круто в какие-нибудь планы разработки ее включить
> > >
> > > Ну вот я изложил выше - там много всего переделывать, причём - с
> > > деградацией производительности в некоторых краевых случаях.  При
> > > этом сама проблема, скажем так, представляется не то чтобы
> > > критичной.  Так что шансов, что мы решим-таки это место
> > > переделывать - не очень много.
> > >
> >
> > с деградацией не надо, конечно.
> > из того, что вы изложили - непонятно, каким именно бекендом обработается
> > запрос - кажется, что
> > можно предположить "если к первому бекенду это последний запрос -
> > принудительно пишем Connection: close"
> >
> > другое дело, что в момент, когда выставляется хедер, непонятно про бекенд
> > вообще ничего - это да.
>
> Сейчас запрос создаётся до того, как что-либо становится известно
> про бэкенды.  И используется этот единожды созданный запрос - для
> всех последующих обращений к любым бэкендам.  Таких обращений
> может быть много, в соответствии с proxy_next_upstream.  Более
> того, иногда "много" - это штатное поведение, скажем при
> "proxy_next_upstream http_404" предполагается, что nginx
> перебирает бэкенды, пока не найдёт тот, на котором есть
> соответствующий ресурс.
>

> Чтобы выставить "Connection: close" - надо менять логику так,
> чтобы запрос создавался уже в процессе обращения к бэкенду, когда
> соединение с бэкендом уже установлено или получено из кэша.  И
> соответственно делать так, чтобы запрос для каждого обращения на
> бэкенд в рамках proxy_next_upstream - создавался заново.
>

с точки зрения протокола http (кроме 2-й версии), в рамках каждого запроса
(на каждый бекенд) отправляется свой заголовок
"Connection: Close" (или Keep-Alive)

кажется, что поменять его во время запроса - не поздно.

то, что на http_404 будет отправляться Connection: close - не криминал,
пусть отправляется



> > > > > keepalive_requests.  Или выставить на бэкенде аналогичное
> > > >
> > > > на бекенде iis, там нет такой крутилки
> > > >
> > > > > ограничение в значение, которое бы было такое же или меньше, чему
> > > > > у nginx'а, и тогда бэкенд будет закрывать соединение сам.
> > > > > Собственно, текущее значение по умолчанию keepalive_requests к
> > > > >
> > > >
> > > > поднимать keepalive_requests в потолок - была такая ошибка.
> > > > мы налетели на примерно такой сценарий
> > > >
> > > > по умолчанию keepalive_requests равен 100. и ... при релоаде старые
> > > воркеры
> > > > довольно быстро завершаются.
> > > > подняли до 4 миллиардов, и на каждый релоад получили плюсом еще 40
> > > > воркеров. и потом память закончилась
> > > >
> > > > keepalive_requests - это ОЧЕНЬ удобный способ завершать http-
> воркеры :))
> > >
> > > Соединения в keepalive'е - что клиентские, что к бэкендам - никак
> > > не должны влиять на завершение рабочих процессов при reload'е.
> > > Они просто закрываются при получении сигнала о перезагрузке
> > > конфигурации и/или если соединение переходит в keepalive, когда
> > > рабочий процесс завершается.  Если влияют - приносите подробности,
> > > будем разбираться.
> > >
> >
> > воркер же будет обрабатывать запросы по уже установленным соединениям,
> пока
> > либо клиент не отключится,
> > либо пока   воркер сам не закроет (при исчерпании keepalive_requests) ?
>
> Keepalive-соединения nginx впрове закрывать в любой момент, и
> именно это он и делает - в любой момент времени, когда бы рабочий
> процесс не попросили завершиться.
>
> Поэтому в случае http - время завершения старых рабочих процессов
> определяется длительностью запросов, и не зависит от того,
> используется ли keepalive или нет.
>
> > а новый релоад приводит к запуску кучи новых воркеров. но не приводит к
> > завершению старых воркеров ?
>
> Reload приводит к запуску новых рабочих процессов, а также к
> команде на плавное завершение старым рабочим процессам.  Плавное
> завершение - подразумевает закрытие всех keepalive-соединений, и
> выход в тот момент, когда открытых соединений (точнее - работающих
> таймеров) не останется, то есть тогда, когда доработают все
> существующие запросы.
>

понаблюдаем


>
> --
> Maxim Dounin
> http://mdounin.ru/
> _______________________________________________
> nginx-ru mailing list
> nginx-ru на nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20180903/c44857a8/attachment-0001.html>


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