Re: TCP_NODELAY и TCP_NOPUSH/TCP_CORK

Igor Sysoev is at rambler-co.ru
Mon Dec 5 00:43:25 MSK 2005


On Mon, 5 Dec 2005, Alexey Polyakov wrote:

> On 12/5/05, Igor Sysoev <is at rambler-co.ru> wrote:
>
>> Да, в Линкусе TCP_CORK (tcp_nopush) и TCP_NODELAY взаимоисключающие, но
>> nginx проявляет недюженный интеллект, пытаясь совместить преимущества
>> обеих опций.
>>
>> "tcp_nopush on" полезно для sendfile(), он в этом случае выводит данные
>> полными пакетами. После того, как весь запрос обработан, TCP_CORK/TCP_NOPUSH
>> выключается, что приводит в сбросу последнего неполного пакета.
>>
>> "tcp_nodelay on" полезно для keep-alive. nginx включает TCP_NODELAY только
>> по окончании запроса, после которого соединение переходит в состоянии
>> keep-alive. До этого nginx выводит данные вызовами writev() достаточно
>> большими порциями для заполнения пакета ("postpone_output 1460"), поэтому
>> данные должны уходить без задержек и TCP_NODELAY не нужен. А вот с последним
>> неполным пакетом может случится небольшая задержка, если соединение не
>> закрывается. Для этого и нужно включить TCP_NODELAY.
>>
>> В Линуксе обработка этих двух опций
>>
>>     tcp_nopush       on;
>>     tcp_nodelay      on;
>>
>> такова:
>>
>> 1) если данные будут выводить комбинацией writev(заголовок)/sendfile(),
>> то проверяется, не было ли уже включен TCP_NODELAY. Если было, то
>> TCP_NODELAY выключается и включается TCP_CORK. По окончании передачи
>> TCP_CORK выключается. Включать TCP_NODELAY не нужно, так как
>> выключание TCP_CORK сбрасывает данные.
>>
>> 2) если при переходе в keep-alive TCP_CORK не была включена, то включается
>> TCP_NODELAY, чтобы сбросить неполный пакет.
>>
>> Кстати, возможно, для "proxy_buffering off" имеет смысл включать
>> TCP_NODELAY до отдачи ответа.
>
> Игорь, я правильно понял, что при проксировании с буферизацией надо
> указывать postpone_output 1460, чтобы заголовки и начало тела ответа
> уходили одним пакетом? Т. е. TCP_CORK при проксировании не
> используется?

postpone_output по умолчанию равен 1460.

TCP_CORK используется, только если для передачи используется комбинация
writev()/sendfile(). Если при проксировании часть ответа будет записана
во временный файл, то ответ будет выводится с помощью writev()/sendfile().


Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list