Http - How Are Parallel Connections Transmitted? - http

I'm taking a google video course about the http protocol. The http 1.1 introduced so called the pipeling technique to reduce a time between requestes and responses. There might occur the head of line blocking, so browsers uses parallel connections to avoid the HOL blocking.
I wonder, how does browsers send parallel network packets? I have never thought about possibility of multiple packets sent simultaneously, is it even possible to send parallel requests through a "cable"? How does it work?
Another thing is the http 2.0, does browsers implement parallel connections in this protocol? The http 2.0 uses the streams, but I'm not sure how browsers handles it.

Nothing in HTTP is truly parallel. If multiple resources are to be tranferred at once, clients have to establish multiple connections. For HTTP/1.1, it is not uncommon to see three to five of these per host.
HTTP/2 is a bit different in that it can engage into interleaving: The smalest entity in HTTP/1.x is a message whereas in HTTP/2 this would be a frame of a message. This allows HTTP/2 to transmit multiple messages "at once" (really: one frame of a given message at a time) while HTTP/1.1 could just start pipelining and possible suffer from HOL-blocking as you mentioned.
As for your question regarding multiple packets being sent simultaneously: Yes, that is possible and is also regularly done. That would concern wave physics, fourier transformations, and electrical engineering and thus be a bit off-topic for SO ;)

Related

Can I have multiple open SSE channels when using HTTP/2?

So far I only used HTTP/1.1, but recently I switched to HTTP/2. On 1.1 I ran into request number limit issues, but HTTP/2 uses one connection with multiplexing, does that mean that I can keep multiple SSE channels open with no problems, or should I still use only one with some internal message routing solution?
If you want to be safe: Use just one channel or only a few of them and multiplex internally.
Longer answer: The reason that more channels caused problems with HTTP/1.1 is that each channel required a dedicated TCP connection, and browsers limited the number of concurrent TCP connections for each tab (I think to something around 10). With HTTP/2 making concurrent HTTP requests is possible on a single connection. therefore opening multiple concurrent SSE streams is more likely be possible. However browsers (and also webservers) may still limit the number of concurrent HTTP/2 streams they support over a TCP connection. HTTP/2 even supports that by allowing each peer in a HTTP/2 setting to communicate the maximum amount of concurrent streams it supports (SETTINGS_MAX_CONCURRENT_STREAMS). To be safe you would need to figure out what the limit is that your target browsers and your web server supports and use a lower number of SSE streams. I unfortunately don't know whether it's part of any HTML or browser specification, that they all should support at least a well-specified number of concurrent requests over HTTP/2. If you keep the number of requests low you avoid to run into problems.
One other advantage for using only a few channels is that you can still support HTTP/1.1 clients well. And not only those which might be directly connected to your server but also those which might connect through a proxy-server (which means the connection browser<->proxy uses HTTP/1.1 and proxy<->webserver uses HTTP/2).

How can HTTP pipelining make performance worse?

It's a popular claim that HTTP pipelining can degrade performance of downloading sites due to the head of line (HoL) blocking phenomena. Is this performance compared to a single non-pipelined persistent HTTP connection or to multiple TCP connections opened simultaneously in order to download resources of the site in parallel?
In the first case I can't really see how large response blocking sending subsequential smaller ones can result in performance loss. Yes, this blocking will occur. But in the case of a single non-pipelined persistent HTTP connection the HoL blocking phenomena occurs every time the client sends a request and every time the server sends a response. The only reasons of performance being potentially worse here I was able to think of are that:
1) the time needed to properly queue/buffer requests/responses may be longer that the time saved by the fact that the server can start processing n-th request without waiting for the processing of (n-1)-th request to complete. But it basically comes down to numbering the requests/responses correctly, so it seems to be more of a concern if many small requests have to be dealt with (it's unlikely that queueing/buffering-related computations will take more time than processing a large response and people indicating that HoL blocking can be a problem refer to large responses, not to small ones) and it is not directly related to the HoL blocking;
2) if many clients had pipelining enabled then it is possible that many large responses would have to be buffered effectively leading to memory exhaustion on the server side. But this is a kind of special situation and clearly it is not what people have in mind when speaking about enabling pipeling in a browser being able to make performance worse.
On the other hand, in the case of comparison of pipelining to multiple simultaneous TCP connections it is readily seen that the necessity to send large response before sending subsequential smaller ones will slow things down.
However, if the comparison is made to a single non-pipelined HTTP connection and pipelining can indeed result in performance loss - can you demonstrate some basic (perhaps simplified) calculations showing that?
I tried to search the response to my question on the Internet but was unable to find it.
Some of the resources that I tried:
https://devcentral.f5.com/articles/http-pipelining-a-security-risk-without-real-performance-benefits
What are the disadvantage(s) of using HTTP pipelining?

Example of HTTP Pipelining vs no pipelining

Can someone give me a concrete example of HTTP with/without pipelining? I always think that both methods can handle multiple requests/responses, except for pipelining case, it only uses one socket, which means only one connection. In contrast, without pipelining, each socket (connection) is unique to each request, so it has the overhead of opening/closing socket. However, with high speed internet today, the difference is negligible. Is that true?
No, even without pipelining, HTTP/1.1 will use a single socket for multiple requests; one after the other. And no, opening a new socket is expensive because it causes additional roundtrips.

Web Browser Parallel Downloads vs Pipelining

I always knew web browsers could do parallel downloads. But then the other day I heard about pipelining. I thought pipelining was just another name for parallel downloads, but then found out even firefox has pipelining disabled by default. What is the difference between these things and how do work together?
As I under stand it, "parallel downloads" are requests going out on multiple sockets. They can be to totally unrelated servers but they don't have to be.
Pipelining is an HTTP/1.1 feature that lets you make multiple requests on the same socket before receiving a response. When connecting to the same server, this reduces the number of sockets, conserving resources.
I think this MDC article explains HTTP pipelining pretty darn well.
What is HTTP pipelining?
Normally, HTTP requests are issued sequentially, with the next request being issued only after the response to the current request has been completely received. Depending on network latencies and bandwidth limitations, this can result in a significant delay before the next request is seen by the server.
HTTP/1.1 allows multiple HTTP requests to be written out to a socket together without waiting for the corresponding responses. The requestor then waits for the responses to arrive in the order in which they were requested. The act of pipelining the requests can result in a dramatic improvement in page loading times, especially over high latency connections.
Pipelining can also dramatically reduce the number of TCP/IP packets. With a typical MSS (maximum segment size) in the range of 536 to 1460 bytes, it is possible to pack several HTTP requests into one TCP/IP packet. Reducing the number of packets required to load a page benefits the internet as a whole, as fewer packets naturally reduces the burden on IP routers and networks.
HTTP/1.1 conforming servers are required to support pipelining. This does not mean that servers are required to pipeline responses, but that they are required to not fail if a client chooses to pipeline requests. This obviously has the potential to introduce a new category of evangelism bugs, since no other popular web browsers implement pipelining.
I recommend reading the whole article since there's more than what I copied into my answer.

Why can HTTP handle only one pending request per socket?

Being curious, I wonder why HTTP, by design, can only handle one pending request per socket.
I understand that this limitation is because there is no 'Id' to associate a request to its response, so the only way to match a response with its request is to send the response on the same socket that sent the request. There would be no way to match a response to its request if there was more than one pending request on the socket because we may not receive the responses in the same order requests were sent.
If the protocol had been designed to have a matching 'Id' for requests and responses, there could be multiple pending requests on only one socket. This could greatly reduce the number of socket used by internet browsers and applications using web services.
Was HTTP designed like this for simplicity even if it's less efficient or am I missing something and this is the best approach?
Thanks.
Not true. Read about HTTP1.1 pipelining. Apache implements it and Firefox implements it. Although Firefox disables it by default.
To turn it on in Firefox use about:config and write 'pipelining' in the filter.
see: http://www.mozilla.org/projects/netlib/http/pipelining-faq.html
It's basically for simplicity; various proposals have been made over the years that multiplex on the same connection (e.g. SPDY) but none have taken off yet.
One problem with sending multiple requests on a single socket is that it would cause inefficient queuing.
For instance, lets say you are in a store and there are 2 cashiers, and 10 people waiting to be checked out. The ideal way to make the line is to have a single queue of 10 people and the next person in line goes to a cashier when they become available. However, if you sent all the requests at once you would probably send 5 people to cashier A and 5 to cashier B. However, what if you sent the 5 people with the largest shopping carts to the same cashier? That's bad queuing and what could happen if you queued a bunch of requests on a single socket.
NOTE: I'm not saying that you couldn't use queuing well, but it keeps it simple to do it right if there is no queuing on a single socket.
There are a few concidertaions I would review.
The first is related to the nature of TCP itself. TCP suffers from 'head-of-line' blocking issue where there can only be a single outstanding (unacknowledged) request (connection/TCP level) in flight. Given traditional latencies this can be a problem from a load time user experience perspective compared to results of parallel connection scheme browsers employ today. The higher the latency of the link the larger the impact of this fundemental limitation.
There is also a concurrency issue in that sometimes you really want to load multiple resources incrementally / in parallel. Back in the day one of the greatest features mozilla had over mosaic was that it would load images and objects incrementally so you could begin to see what was going on and use a resource without having to wait for it to load. With fewer connections there is a risk in that for example loading a large image on page before a style sheet can be catastrophic from an experience point of view. Expecting some kind of mitigating intelligence or explicit configuration to optimally order requests may not be a realistic or ideal solution.
There are proposals such as HTTP over SCTP that will more or less totally correct the issue you raise at the transport level.
Also realize that HTTP doesn't necessarily mandate a Content-Length header to serve data. Even if each HTTP response was ID'd, how would you manage streaming binary content with no content length (HTTP/1.0 style)? or if the client sent the Connection: close header to have the client close due to non-known lengths?
To manage this you would have to HTTP chunk (already present) in multiplex (I don't think anyone implements this) and add some non-trivial work to many programs.

Resources