2018-05-04 14:46 GMT+02:00 Luca Toscano <toscano.l...@gmail.com>:

> Hi everybody,
>
> as part of the plan to add more documentation about httpd's internals I am
> trying to debug more tricky bugs (at least for me) reported by our users,
> in order for example to better understand how the filters chain works in
> depth.
>
> This one caught my attention, and after a bit of testing I have some
> follow up questions, if you have time let me know your thoughts :)
>
> 2018-04-19 13:47 GMT+02:00 <nerbr...@free.fr>:
>
>> Hello all,
>>
>> I'm using Apache 2.4.24 on Debian 9 Stable, behind a DSL connection, with
>> an estimated upload capacity of ~130kB/s.
>> I'm trying to limit the bandwidth available to my users (per-connection
>> limit is fine).
>> However, it seems to me that the rate-limit parameter is coarsely grained
>> :
>>
>> - if I set it to 8, users are limited to 8 kB/s
>> - if I set it to 20, or 30, users are limited to 40 kB/s
>> - if I set it to 50, 60 or 80, users are limited to my BW, so ~120 kB/s
>>
>>
> After following up with the user it seems that the issue happens with
> proxied content. So I've set up the following experiment:
>
> - Directory with a 4MB file inside
> - Simple Location that proxies content via mod_proxy_http to a Python
> process running a webserver, capable of returning the same 4MB file
> outlined above.
>
> I tested the rate limit using curl's summary (average Dload speed for
> example).
>
> This is what I gathered:
>
> - when httpd serves the file directly, mod_ratelimit's output filter is
> called once and the bucket brigade contains all the data contained in the
> file. This is probably due to how bucket brigates work when morphing a file
> content?
>
> - when httpd serves the file via mod_proxy, the output filter is called
> multiple times, and each time the buckets are maximum the size of
> ProxyIOBufferSize (8192 by default). Still not completely sure about this
> one, so please let me know if I am totally wrong :)
>
> The main problem is, IIUC, in the output's filter logic that does this: it
> calculates the size of a chunk, based on the rate-limit set in the httpd's
> conf, and then it splits the bucket brigade, if necessary, in buckets of
> that chunk size, interleaving them with FLUSH buckets (and sleeping 200ms).
>
> So a trace of execution with say a chunk size of 8192 would be something
> like:
>
> First call of the filter: 8192 --> FLUSH --> sleep(200ms) --> 8192 --> ...
> -> last chunk (either 8192 or something less).
>
> This happens correctly when httpd serves directly the content, but not
> when proxied:
>
> First call of the filter: 8192 -> FLUSH (no sleep, since do_sleep turns to
> 1 only after the first flush)
>
> Second call of the filter: 8192 -> FLUSH (no sleep)
>
> ...
>
> So one way to alleviate this issue is to move do_sleep to the ctx data
> structure, so if the filter gets called multiple times it will "remember"
> to sleep between flushes (with the assumption that it is allocated for each
> request). It remains the problem that when the rate-limit speed sets a
> chunk size greater than the ProxyIOBufferSize (8192 by default) then the
> client will be rate limited to the speed dictated by the buffer size (for
> example, 8192 should correspond to ~40KB/s).
>
> Without the patch of do_sleep in ctx though, as reported by the user,
> after some rate-limit there won't be any sleep anymore and hence almost no
> ratelimit (only FLUSH buckets that might slow down the overall throughput).
>
> Thanks for reading so far, I hope that what I wrote makes sense. If so,
> I'd document this use case in the mod_ratelimit documentation page and
> possibly submit a patch, otherwise I'll try to study more following up from
> your comments :)
>
>
>
To keep archives happy: opened
https://bz.apache.org/bugzilla/show_bug.cgi?id=62362 and added a patch in
there, if anybody wants to review it and give me suggestions I'd be happy :)

Thanks!

Luca

Reply via email to