- From: Willy Tarreau <w@1wt.eu>
- Date: Tue, 24 Jun 2014 20:15:54 +0200
- To: bizzbyster@gmail.com
- Cc: HTTP Working Group <ietf-http-wg@w3.org>
On Tue, Jun 24, 2014 at 01:50:33PM -0400, bizzbyster@gmail.com wrote: > I've raised this issue before on the list but it's been a while and reading > Mark's ops guide doc (https://github.com/http2/http2-spec/wiki/Ops) I'm > reminded that requiring the use of a single connection for HTTP/2 ("Clients > SHOULD NOT open more than one HTTP/2 connection") still makes no sense to me. > Due to multiplexing, HTTP/2 will naturally use FEWER connections than HTTP/1, > which is a good thing, but requiring a single connection has the following > drawbacks: > > Servers must keep open idle connections, making load balancing more complex > and creating DOS vulnerability. They're not forced to, it's just like with persistent connections in 1.1, they're free to close them when they don't want to, which will cause the client to reopen a new one when needed. > Servers must turn off tcp_slow_start_after_idle in order for browsers to get > good performance, again creating DOS vulnerability. It's not that black and white. If you fetch multiple objects over a single connection, you have less chances of reaching an idle state. However if you open many connections, each of them starts with a slow start. So if you do nothing (do not turn off tcp_slow_start_after_idle), you should at least get the level of performance you have with multiple connections, with the possibility that sometimes you don't go idle and gain even more. > The number of simultaneous GET requests I'm able to upload in the first round > trip is limited to the compressed amount that can fit in a single initcwnd. > Yes compression helps with this but if I use multiple connections I will get > the benefit of compression for the requests on the same connection, in > addition to having multiple initcwnds! Yes, but many people are against this (the buffer bloat problem), but see below. > The amount of data I'm able to download in the first round trip is limited to > the amount that can fit in a single initcwnd. Which is the exact purpose of initcwnd : send what is almost sure to be deliverable without overflowing every router in the path. I think that's the main motive for this. > Head of line blocking is exacerbated by putting all objects on a single > connection. I absolutely agree, and this will be emphasized over lossy networks such as WiFi. This is one point which might cause some future updates or new recommendations (or at least practises). > Multiple short-lived HTTP/2 connections gives us all the performance benefits > of multiplexing without any of the operational or performance drawbacks. Not exactly. For each side's TCP stack, multiple connections in parallel will cause an increased usage of TCP buffers. Of course you also have the extra cost of accepting/closing a connection and the network overhead of the opening and closing handshakes. The smallest HTTP/1.1 exchange you can do today over a short-lived connection is 5 packets using a piggy-back request, a delayed ack on the server and merging the FIN with the response : client SYN server ---------------------> SYN-ACK <--------------------- Request ---------------------> Response + FIN <--------------------- RST ---------------------> The smallest you can do using a persistent connection is 3 packets : client Request server ---------------------> Response <--------------------- ACK ---------------------> The difference is the volume of a SYN and a SYN-ACK (both of which carry options, count around 50-60 bytes each on average). So from a network point of view, short-lived connections have an extra cost : +66% packets on small objects, +120 bytes. > As a > proxy and a browser implementor, I plan to use multiple HTTP/2 connections > when talking to HTTP/2 servers because it seems like the right thing to do > from a performance, security, and operational perspective. To be honnest, I'm pretty sure that in a first time I'll have to do the same in haproxy because of the massive complexity increase introduced by HTTP/2. It will require a general architecture change and mixing that with stream multiplexing at the same time is suicidal. But in the long term, I hope that we'll get it to work reliably with muxed connections on both sides. The issue is that all of the burden to make the protocol efficient for both clients and servers will rely on the shoulders of intermediary implementers like us, and that's clearly not an easy task :-( > I know it's very late to ask this but can we remove the "SHOULD NOT" > statement from the spec? Or, maybe soften it a little for those of us who > cannot understand why it's there? Note that a "SHOULD NOT" is not a "MUST NOT", it basically means "MUST NOT unless you have no other choice". At the beginning I'll clearly be in that situation. What I suspect in fact is that when HTTP/2 starts to take off, we'll have far more HTTP/1 traffic than HTTP/2, and the concurrency of HTTP/1 streams vs HTTP/2 streams will make HTTP/2 very inefficient over congested networks, incitating browser editors to start to open multiple connections again, just to compete fairly with the 1.1 traffic around. I hope that the future will prove me wrong however... Regards, Willy
Received on Tuesday, 24 June 2014 18:16:19 UTC