How do proxy_module response buffering options work?
Maxim Dounin
mdounin at mdounin.ru
Mon Apr 25 22:53:10 MSD 2011
Hello!
On Mon, Apr 25, 2011 at 10:27:05AM +0200, Hongli Lai wrote:
> Maxim Dounin wrote in post #994792:
> > No, nginx passes downstream chain of buffers, not a single buffer.
>
> I understand this, but I don't understand how there can be more than 1
> buffer at a time that's only partially passed downstream. I had in mind
> that it works like this:
>
> Suppose that Nginx is configured with 4 buffers, each 100 bytes in size.
> The upstream response is 400 bytes.
> Bytes 0-99 from the response are put in buffer 1, bytes 100-199 are put
> in buffer 2, bytes 200-299 are put in buffer 3, bytes 300-399 are put in
> buffer 4.
> Nginx flushes buffer 1 downstream, thus buffer 1 is now a "busy buffer"
> while all the other ones are not. Only when buffer 1 is entirely flushed
> will Nginx continue to flush buffer number 2 (buffer 1 is now marked
> "ready" of some sort so that it may be reused.)
>
> How can there be multiple busy buffers? Is my description correct?
No. nginx passes downstream (or, more precisely, passes to output
filter chain) multiple buffers, and these buffers can't be reused
unless completely send (see below).
E.g. with 4 buffers as in your example something like this
happens:
1. nginx gets 0-99 from upstream to buf 1, and calls output filter
on it.
>From this point buf 1 is busy - it can't be touched unless
completely send, as some filter may have been already modified it
(e.g. converted charset in charset filter) or done some other
related work on it (e.g. added chunk-size as per chunked transfer
encoding). We can't spool it to disk and so on.
2. nginx gets 100-199 from upstream to buf 2, and calls output
filter on it. The same as the above now applies to buf 2 as well.
Buffers 1 and 2 are now linked somewhere along output filter chain
(most likely in writer filter, waiting for client to allow sending
of additional data).
(Both (1) and (2) may also happen at the same time with single
output filter call if data to both buffers happened to be read at
once.)
Somewhere near here proxy_busy_buffers_size starts to play it's
role: once data is read to buffers 3 and 4 - they are not passed
to output filter (assuming proxy_busy_buffers_size is 200) and
nginx may spool data to disk and reuse these buffers to read more
data from upstream.
(Obviously the case with 400-byte response isn't intresting: if we
have enough buffers to read the whole response all buffers will be
just passed to output filters. All of the above is actually
needed when the response is bigger than the available buffers.)
Maxim Dounin
More information about the nginx
mailing list