Re: HAPROXY & pool of keep-alive connections to backend

From: Willy Tarreau <w#1wt.eu>
Date: Sun, 12 Sep 2010 22:47:49 +0200


On Sun, Sep 12, 2010 at 01:23:49PM -0700, dormando wrote:
> >
> > This mechanism (connection multiplexing) will be worked on once we have
> > server-side keep-alive. There are several issues doing this. HTTP only
> > allows you to send an idempotent request over a keep-alive connection,
> > because if the connection closes while you're sending, you have to re-emit
> > the request without knowing if it was processed or not. So basically you
> > must not send POSTs nor any request looking like a dynamic request, which
> > limits the feature to static files. I know that some vendors tend to do
> > that on anything because it looks better. Just ask them what customers
> > use that on your payment requests ;-)
>
> You know, we've had this in perlbal for half a decade or so. Have you
> tested the implementation at all? Perlbal sits in front of almost
> everything, and mostly with backend keepalives enabled. On paranoid/broken
> systems you can always leave client persist on and disable backend
> persist, but you add some latency.
>
> If nothing else, I'd be curious to know what real bugs perlbal has
> relative to backend keepalives, so we can document them at least.

I'm not even speaking about a specific implementation but about HTTP. HTTP provides no way to announce that a keep-alive connection will close. So in general it can close while you are sending a request over it. HTTP says that when this happens, you just apply a classical back-off algorithm and reconnect and push your request again. The problem here is that if the connection closes just after the request reaches the server, then the server may have started processing it, and will do it once again when the second request arrives. If that's an idempotent request, no problem. If that's a POST or a GET with side effects, then it's a different story. Many applications are protected against undesired "reload" effects, because users are humans an may very well do the mistake themselves. But not all applications are designed that way, and if your browser still warns you when you hit "reload" after a POST, it's precisely because of that.

If you want to add such info to the doc, it's explained here in RFC2616, paragraph 8.1.4 :

   A client, server, or proxy MAY close the transport connection at any    time. For example, a client might have started to send a new request    at the same time that the server has decided to close the "idle"    connection. From the server's point of view, the connection is being    closed while it was idle, but from the client's point of view, a    request is in progress.

   This means that clients, servers, and proxies MUST be able to recover    from asynchronous close events. Client software SHOULD reopen the    transport connection and retransmit the aborted sequence of requests    without user interaction so long as the request sequence is    idempotent (see section 9.1.2). Non-idempotent methods or sequences    MUST NOT be automatically retried, although user agents MAY offer a    human operator the choice of retrying the request(s). Confirmation by    user-agent software with semantic understanding of the application    MAY substitute for user confirmation. The automatic retry SHOULD NOT    be repeated if the second sequence of requests fails.

As you can see, the rules are quite clear and strict on that matter. However, I think that the last point may allow an intermediary with a list of retryable URLs to retry the request once. After all, if the site's admin configures a full list of the idempotent requests in the load balancer, we might consider that the load balancer gets semantic understanding of the application.

Regards,
Willy Received on 2010/09/12 22:47

This archive was generated by hypermail 2.2.0 : 2010/09/12 23:00 CEST