Persistent HTTP connections && Pipelining

Gena Makhomed makhomed at pbank.lutsk.ua
Wed Nov 14 05:31:33 MSK 2007


Здравствуйте, Anton!

Wednesday, November 14, 2007, 0:47:03, you wrote:
...
AY> на Keep-Alive мы сэкономили 0.80 ms на один запрос.
AY> (машины соеденены стомегабитной сетью, на гигабите разница будет меньше)

AY> Типичное время ответа бэкенда раздающего динамику - 100 ms
AY> Т. е. Keep-Alive позволит его сократить примерно на 1%.

прирост производительности сервера на 1% - это не так уж и мало.
если backend обрабатывает запрос не 100ms, а 50ms, или 25ms -
этот 1% превращается в ~3-5% прироста производительности.

например, при DDOS-атаке, когда много клиентов
очень часто запрашивают одну и ту же информацию,
запросы из PHP к MySQL закешируются в memcached,
и среднее время ответа на один запрос уменьшится.

или mass virtual hosting, когда nginx используется
как http accelerator для проксирования всех подряд
запросов клиентов на backend. динамика будет отдаваться
~100ms, статика <10ms. в среднем на одну веб-страницу
будет 1 динамика и несколько десятков запросов статики.
прирост производительности получится заметно больше 1% (?)

отдавать напрямую статику клиентов через nginx нельзя,
потому что не обрабатывается .htaccess и отдаются симлинки.

есть еще варианты, когда для некоторых запросов backend
находится за пределами локальной сети и frontend к нему
подключается по протоколу https. в этом частном случае
Persistent HTTP connection также было бы очень кстати.

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

>> Pipelining - это способ еще больше ускорить обработку
>> запросов, потому что клиент может отправить несколько
>> запросов "пачкой" не дожидаясь завершения обработки
>> предыдущего запроса перед отправкой следующего,
>> тогда backend вообще не будет простаивать
>> в ожидании нового запроса от frontend`а
>> после обработки предыдущего.

AY> Как это выглядит с точки зрения фронтенда:

AY> сейчас как только получен запрос от клиента, посылается запрос на бэкенд

AY> если делать pipelining то фронтенд должен будет подождать
AY> еще один запрос (немного увелилчивая response time
AY> для первого), потом послать оба зпроса разом.

в LAN pipelining запросов между frontend`ом и backend`ом дополнительно
усложнит обработку директив proxy_next_upstream и fastcgi_next_upstream,
а также параметра weight=число директивы server в контексте upstream.
недостаток: усложнение кода сервера, в этом случае преимуществ нет.

если upstream всего один и подключен по каналу с высоким уровнем
латентности (линк через спутник, перегруженный канал связи и т.п.)
request pipelining может дать в этом случае ощутимый performance boost.
тем более, что обычно на удаленных https-серверах находятся веб-сервисы,
и латентность получения ответов от удаленного сервера
желательно иметь как можно меньшую.

AY> Сами по себе Keep-Alive и Pipelining это конечно полезные
AY> возможности протокола HTTP, но реально нужны они только
AY> на участке между конечным клиентом (который обычно имеет
AY> сравнительно медленный канал) и сервером.

Ok. понял, спасибо.

PS кстати, есть еще один способ, как можно получить побольше
производительности из веб-сервера, если frontend и backend
находятся физически на одном сервере - чтобы backend получал
запросы от nginx`а через unix socket, тогда можно будет
получить дополнительное повышение производительности
из-за отсутствия overhead`а связанного с tcp протоколом.

nginx это умеет,
только вот apache/apache2 насколько я знаю, не умеет принимать
запросы от frontend`а через unix socket, а только через tcp/ip.
но судя по тому, что нигде в публичном доступе таких backend`ов
нет, прирост производительности здесь будет не очень большим?

Wednesday, November 14, 2007, 2:17:21, you wrote:

AY> Когда фронтенд для подключения к бэкенду не использует Keep-Alive
AY> то падание запроса к первому освободившемуся процессу произойдет атоматически
AY> (он сделает accept и заберет коннекцию из listen queue). В случае если
AY> фонтенд использует Keep-Alive он сам должен организровать очередь запросов
AY> и отпрвить запрос из очереди тому процессу, который перым пришлет ответ
AY> и таким образом сообщит, что он освободился.

у frontend`а ведь в любом случае есть очередь http запросов.
а когда отправлять запрос backend`у - после получения event`а
или после получения ответа от backend`а - почти одно и то же. (?)

кстати, в случае с Keep-Alive подключенем на backend это может быть
даже более эффективно, потому что можно будет сначала отправить новый
запрос backend`у, не заставляя его ждать запрос ни одной милисекунды,
и только после этого уже заняться обработкой старого ответа backend`а,
скачивая его по локальной сети из tcp-буферов ядра backend-сервера. (?)

новый event nginx`ом будет обрабатываться не в тот же момент, когда
он начал обработку ответа от backend`а, а с некоторой задержкой. (?)

AY> $ ab -n 5000 http://apache_1.3_server/small_static_file
AY> $ ab -k -n 5000 http://apache_1.3_server/small_static_file

если файл не мелкий, разница между keep-alive и не keep-alive
подключениями nginx<=>backend будет все-таки больше 0.8 ms (?)

-- 
Best regards,
 Gena                            mailto:makhomed at pbank.lutsk.ua







More information about the nginx-ru mailing list