Trouble with HTTP request queueing when using HTTP/2 frontend and HTTP/1.1 backend

2022-03-21 Thread Jens Wahnes

Hello,

I'm a happy user of HAProxy and so far have been able to resolve any 
issues I've had by reading the docs and following the answers given on 
this mailing list or online tutorials. But now I've run into a problem I 
cannot resolve myself and hope someone could help me figure out what 
might be wrong.


The setup I have has been running fine for many months now. HAProxy 
terminates TLS for HTTPS requests and forwards these requests to a 
couple of backends. The backend servers are HTTP/1.1 only. As long as 
the frontend is limited to HTTP/1.1, the special backend I use for file 
uploads is operating exactly as intended. After enabling HTTP/2 on the 
frontend, however, the file upload backends are not working as before. 
The requests will not be processed properly and run into timeouts.


These file upload backends in my HAProxy configuration are somewhat 
special. They try to "serialize" certain HTTP file upload requests made 
by browser clients via AJAX calls (i.e. drag-and-drop of several files 
at once into the browser window). These files need to be processed one 
after the other per client (not in parallel). So the HAProxy backend in 
question uses a number of servers with a "maxconn 1" setting each, which 
will process the first request immediately but queue subsequent HTTP 
requests coming in at the same time until the previous request is 
finished. This approach certainly is not perfect in design, but has been 
working for me when using a somewhat high arbitrary number of 
pseudo-servers to realize it, so that each client making these file 
upload requests will be served by one "server" exclusively. This is what 
the backend definition looks like:


backend upload_ananas
option forwardfor if-none header X-Client-IP #except 127.0.0.0/8
stick-table type string len 32 size 10k expire 2m
stick match req.cook(mycookie),url_dec
stick store-request req.cook(mycookie),url_dec
timeout server 10m
timeout queue  20s
balance hdr(Cookie)
default-server   no-check maxconn 1 maxqueue 20 send-proxy-v2 track 
xy/ananas source "ipv6@[${BACKENDUSEIPV6}]"

server-template a 32 "${ANANAS}":9876


Once I switched the HTTP frontend to use HTTP/2 (using "alpn 
h2,http/1.1"), this special backend is not working as expected anymore. 
All is fine as long as there is only one request present for a certain 
server at any given time. However, when there are two or more requests 
at the same time, i.e. as soon as the queueing mechanism is supposed to 
kick in, the setup is not working the way it does with a HTTP/1.1 
frontend. The parallel requests aren't properly put into the queue (or 
taken out of the queue) in this case. From what I can see in the log 
file, the requests seem to be blocking one another, and nothing is 
happening until the timeout set by "timeout queue" is reached. At that 
point, 1 or 2 out of 4 requests in an example call may succeed, but the 
others will fail.


Clearly, this kind of setup is quite the opposite of what most people 
will be using. In my case, I'm deliberately trying to stuff requests 
into a queue, whereas normally, one would try to move requests to a 
server that has got slots open for processing. So I think that my use 
case is hitting different code paths than most other setups.


I've read in previous emails on the mailing list that the "maxconn" 
setting nowadays does not limit the number of TCP sessions to the 
backend server, but the number of parallel HTTP requests. This made we 
wonder if the trouble I'm seeing might have to do with the way 
multiplexed HTTP/2 requests are mapped to HTTP/1.1 backends. Could it be 
that when the backend server finishes  processing the first request, 
this isn't generating a proper event in HAProxy's backend logic, so that 
the next request is not being processed when it could? Or maybe there is 
something special about the number of "0" free slots in the server 
definition in this case, once the first slot has been taken?


Trying to work around the problem, I've switched on and off quite a few 
settings that may influence the way processing takes place, but still 
haven't been able to come up with a working configuration in the HTTP/2 
case. Some of the settings I tried were:

  * default-server max-reuse 0
  * http-reuse never
  * option http-server-close
  * option httpclose
  * option http-buffer-request
  * retry-on conn-failure 408 503
  * http-request wait-for-body time 15s at-least 16k if METH_POST

With HTTP/2 active, there will be log entries like this (I re-ordered 
them to be in order of begin of processing).


Mar 18 17:30:31 localhost haproxy[478250]: fd90:1234::21a:52738 
[18/Mar/2022:17:29:51.411] Loadbalancer~ zyx_ananas/a24 
12/0/1/40112/40125 200 1217 mycookie=3BRoK6tyijmqndBJRzLyT9Lq7dsiPmeT - 
 356/356/1/0/0 0/0 {serialize.example.com} "POST 
https://serialize.example.com/services/ajax.php/file/upload HTTP/2.0"
Mar 18 17:30:11 localhost haproxy[478250]: fd90:1234::21a:52738 

Re: http/2 Frontend

2017-12-04 Thread Willy Tarreau
On Mon, Dec 04, 2017 at 11:26:49AM +0100, Daniel wrote:
> Ahh found it:
> 
> bind :443 ssl crt /path/to/cert.crt alpn h2,http/1.1

Indeed, I had a hard time figuring what to write in the doc because
aside this there's nothing else to do. Our architecture manual is
outdated, and that's definitely where it should have been explained.

> Need to test it ;)

I just fixed another annoying bug, better pick the git repo or a daily
snapshot tomorrow morning.

Cheers,
Willy



Re: http/2 Frontend

2017-12-04 Thread Daniel
Ahh found it:

 

bind :443 ssl crt /path/to/cert.crt alpn h2,http/1.1

 

Need to test it ;)

 

Cheers

 

 

Von: Daniel <dan...@linux-nerd.de>
Datum: Montag, 4. Dezember 2017 um 11:21
An: HAProxy <haproxy@formilux.org>
Betreff: http/2 Frontend

 

Hi There,

 

i know that haproxy 1.8 is able now to handle http/2 connections in the 
frontend.

My Problem is, I cant find any Documention for 1.8 on the Website.

 

Has someone some Exmaple configs for me just to check how I need to configure 
it?

 

Cheers

 

Daniel



Re: http/2 Frontend

2017-12-04 Thread Jérôme Magnin
On Mon, Dec 04, 2017 at 11:20:29AM +0100, Daniel wrote:
> Hi There,
> 
> i know that haproxy 1.8 is able now to handle http/2 connections in the 
> frontend.
> My Problem is, I cant find any Documention for 1.8 on the Website.
> 
> Has someone some Exmaple configs for me just to check how I need to configure 
> it?
> 
> Cheers
> 
> Daniel
>

Hello Daniel,

look for the alpn keyword in the doc.
https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.1-alpn

regards,
Jérôme 



http/2 Frontend

2017-12-04 Thread Daniel
Hi There,

 

i know that haproxy 1.8 is able now to handle http/2 connections in the 
frontend.

My Problem is, I cant find any Documention for 1.8 on the Website.

 

Has someone some Exmaple configs for me just to check how I need to configure 
it?

 

Cheers

 

Daniel