ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Вопросов накопилось по ра боте с буферами. И как оп тимально буферизовать в есь исходящий поток внут ри фильтра?


  • To: nginx-ru@xxxxxxxxx
  • Subject: Вопросов накопилось по ра боте с буферами. И как оп тимально буферизовать в есь исходящий поток внут ри фильтра?
  • From: Валентин Бартенев <ne@xxxxxxxx>
  • Date: Thu, 2 Dec 2010 11:13:57 +0300

Добрый день. Надеюсь на помощь гораздо более опытных, чем я.

Мне в модуле-фильтре необходимо буферизовать весь ответ, сложив все in chains 
в два целиковых буфера. Размер первого всегда заранее известен, размер второго 
зависит от размера данных и известен только в случае если уже установлен 
заголовок content-length. После этого, на основе этих двух полученных буферов 
формируется совершенно новый набор данных, которые уже посылаются дальше.


Как сделал я. Я создаю первый буфер, его размер всегда известен заранее и 
копирую туда данные из приходящих in chains, пока он не заполнится. Также я 
решил сделать небольшую оптимизацию, в случае, если все необходимые для него 
данные и так содержатся в пределах одного пришедшего буфера, я использую его, 
вместо создания своего и копирования туда.

И тут первый вопрос возник. Я обнаружил, что таким образом я блокирую механизм 
повторного использования освобожденных буферов в ngx_output_chain, которую 
передо мной вызывает copy-фильтр. Вызывается функция ngx_chain_update_chains, 
которая в случае использования мной первого пришедшего буфера в итоге всегда 
делает break на первой же итерации. Получается фиговая оптимизация, и лучше в 
моем случае всегда копировать данные в свой созданный буфер, или эту пустяки?

Далее, мне нужно заполнить оставшимися данными второй буфер. Если заголовок 
content-length установлен, то я поступаю аналогично первому буферу. Если нет, 
то я сначала складываю отдельно все приходящие цепочки образуя одну большую 
единую цепь из данных, попутно считая их размер, а затем уже, по получении 
последнего буфера с признаком last_buf, создаю свой второй единый буфер, зная 
размер всех данных, и копирую туда их из собранной цепи.

Опять же такой подход не дает высвобождать буфера до последнего момента. Кроме 
этого, как я понял, я не могу просто соединять цепочки, используя приходящие 
звенья. Мне необходимо создавать свою цепь звеньев, копируя в них указатели на 
буфера. Просто соединение приходящих цепей в некоторых случаях приводит к 
зацикливанию nginx уже упомянутым вызовом ngx_chain_update_chains из 
ngx_output_chain, так цепь в busy замыкается сама на себя при определенных 
обстоятельствах.

В image_filter сделано гораздо проще, там если размер картинки заранее 
неизвестен, то выделяется буфер размером "image_filter_buffer" (по-молчанию 
1Мб) и данные складываются в него, если их оказывается больше, то не повезло, 
ошибочка, если меньше, то излишек простаивает впустую. Неужели такой подход 
оптимальнее, чем буферизация цепочки с целью вычисления размера данных? Может 
мне тоже так сделать?


Заполнили два буфера всеми пришедшими данными. Теперь, если все Ок, происходит 
генерация нового потока данных. Я начинаю выделять буфера по мере наполнения 
размером ngx_pagesize выстраивая из них новую цепочку, которую затем и посылаю 
далее. Как бы тут сэкономить? В принципе, я могу использовать один из уже 
созданных буферов, но этого, как правило недостаточно. В то же время, в цепях 
busy и free внутри ngx_output_chain_ctx_t скопилось куча уже неиспользуемых 
буферов, можно ли взять от туда? Или можно их сразу складывать у себя 
"прозапас"? И как лучше сделать? Или еще откуда-то можно взять? Или лучше не 
стоит, и я все правильно делаю?

Надеюсь на ваши разъяснения и подсказки. Возможно некоторые механизмы в nginx, 
я еще пока плохо понимаю.

И не могли бы кто-нибудь пояснить назначение и использование в некоторых 
местах shadow и last_shadow у буферов?

--
Валентин Бартенев

_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://nginx.org/mailman/listinfo/nginx-ru


 




Copyright © Lexa Software, 1996-2009.