Hi Stefan,

I've had a real lack of time lately to do much on trunk's mod_http2 on the windows side. The new mod_proxy_http2 requires a few functions from mod_http2 and with what time I have had I have been unsuccessful figuring out how to get these functions exported. So if you (or anyone else) can figure this out, I'd appreciate it.

Gregg

On 2/26/2016 9:06 AM, Stefan Eissing wrote:
Things winding down here a bit before the weekend (at least I try) and I thought
I'd summarize a bit the state of HTTP/2 in our little project, because...well, 
some
might be interested and certainly no one has the time to follow all my crazy 
submits.

* trunk<->  2.4.x
   the version in 2.4.x has gathered a bit dust, as we made several tweaks in 
trunk
   in regard to async connection handling and scoreboard updates. These have 
all been
   backported, except one. Once that is through, I'll make a backport of 
mod_http2,
   so that 2.4.x gets all the nice new things.

* nice new things
   in trunk we have the following additions:
   - http/2 connections get queued properly when they become idle on the event 
mpm.
     that should be nice for people with many connections or long keepalives 
configured.
   - timeouts and keepalive timeouts are respected as for http/1 connections, 
no extra
     configuration.
   - stability: with the interim releases in github and the help of nice 
people, several
     improvements have been made here and the 1.2.5 github has no reported open 
blockers,
     hanging connections or segfaults. All those changes are in trunk.
   - server push: the module now remembers in each open connection which 
resources
     have already been pushed, using hash digests. This also implements an 
outsketched
     extension https://datatracker.ietf.org/doc/draft-kazuho-h2-cache-digest/ 
whereby
     clients can send a highly compressed digest of the resources they have. 
This is
     very early and experimental and we'll see how/if browsers adapt this and 
how
     it will change over time.
   - To offload worker threads, the module allows a number of file handles to 
have
     open. So, ideally, when serving static content, workers just lookup the 
file,
     return and the master connections streams them out. This number existed 
before
     as number per master connection. Now this number is multiplied by the 
number of
     workers and made a process wide pool where h2 connections can borrow 
amounts.
     Still, I am not totally satisfied with this. This should not be 
configurable, but
     httpd itself should check for ulimits of the process and configure itself, 
I think.
   - the scoreboard shows more information for h2 connections, such as its 
connection
     state and some stream statistics. Maybe the h2 workers should show up in a 
separate
     section on day...
      127.0.0.1 http/1.1        test2.example.org:12345 wait, streams: 
1/100/100/0/0 (open/recv/resp/push/rst)
   - request engines! which leads us to:

  * mod_proxy_http2
    is configured just like other proxy modules with by using 'h2' or 'h2c' as 
url prefix
    in the configuration directives.
    <IfModule proxy_http2_module>
        <Proxy "balancer://h2-local">
            BalancerMember "h2://test2.example.org:12346"
        </Proxy>
         ProxyPass "/h2proxy" "balancer://h2-local"
         ProxyPassReverse "/h2proxy" "balancer://h2-local"
     </IfModule>
     Initially, it used one h2 connection for one request. The connection, and 
the http2
     session associated with it, was reused via the nice proxy infrastructure.

     This is how things still are when the original connection is http/1.1
     When this is http/2 itself, however, the first such request will register a
     "request engine" that will accept more requests while the initial one is 
still
     being served and use the same backend connection for it. When the last 
assigned
     request is done, it unregisters and dissolves into fine mist.
     The connection and h2 session stays as before, so a new request can reuse 
the connection
     in a new engine.

     This works quite (but not 100%) reliable at the moment. There are still 
some races when
     requests are sent out while the backend is already shutting down and the 
retry does
     not catch all cases.

     Important here is that requests for engines process all the usual hooks 
and filters
     and yaddayadda of our infrastructure, just like with http/1.1. This works 
as follows:

     - incoming request is handed to a worker thread as is done for all by 
mod_http2
     - httpd/proxy identifies the handler of mod_proxy_http2 as the responsible
     - mod_proxy_http2 finds out what backend it shall talk to and ask from 
mod_http2
       (if present, the usual optionals) if there is already an engine for this 
backend,
       and that it is willing to host one if there is not.
     - mod_http2, if it has one, *freezes* the task for this request (which 
holds the
       replacements for the core input/output filters on this slave connection) 
and
       returns that it will take care of it, once the handler is done. The 
handler then
       just returns as if it had processed the request.
       Upon return of the worker, the mod_http2 sees a frozen task and makes it 
ready
       for processing in an engine. Next time the engine polls for more 
requests, it is
       forwarded.

     - What is this freezing? Basically, an additional output filter that saves 
all
       incoming buckets for later. So, the EOR bucket is set aside here, for 
example.
     - Is it fast? No, not yet. Flow control handling is not optimal and I am 
sure there
       are lots of other places that can be improved.
     - Then why? This way of handling proxy requests saves connections to the 
backend
       and threads in the server process. That should be motivation enough. If 
httpd
       is a reverse proxy, then doing the same work with 1-2 orders of 
magnitude less
       file handles and threads should be interesting.
     - And: it could be done for mod_proxy_http, too! I see no reason why a 
single
       thread cannot use pollsets to juggle a couple of http/1.1 backend 
connections
       on top of a http/2 master connection.

Anyways, let me hear what you think. Anyone wants to help?

-Stefan



Reply via email to