Hi Dylan,

On Tue, Jan 27, 2009 at 12:13:04PM +1100, Dylan Egan wrote:
> Hi,
> 
> I want to understand the process a bit more to clarify whether or not
> a retry should be occurring in this situation. Essentially I have a
> pretty standard haproxy setup and it has 7 backend servers. Now when a
> request comes in and it hits one of these servers (they're mongrels)
> and that server happens to be killed by monit the request will result
> in a 502. Is this the expected behaviour?

yes

> I am using retries 3 and the
> redispatch option, but I'm not sure if in this case, when the backend
> server has received a request which then dies off, if haproxy should
> retry on another backend server or not.

it must not retry because it cannot ensure that part of the request
has not been processed and caused some database changes. HTTP says
that only idempotent requests may be retried. A DELETE, PUT, and in
theory a GET could be retried, though we all know a lot of applications
with non-idempotent GET requests.

For instance, imagine you're filling a form on a site to buy a book.
You click OK and the server dies in the middle of the processing. You
don't know if your order has been recorded or not. In this case, only
the user can control that. If you get a 502 (or get redirected to a
sorry page), you get back to your basket and can check whether your
order has been validated or not. If haproxy decides on your behalf to
retry on another server, it does not let you check whether it can retry
or not.

There's a gray area though. In theory, we can retry a request if the
error occurs in the middle of the request. That means, you have not
sent the complete GET request, or the complete POST data. But those
are very rare cases because a GET request will always be sent at once,
and a POST request has little chance to be retried once the first
data has been pushed out of the buffer and replaced with new data.

What *could* be accomplished though (and what I want to implement
with HTTP/1.1) is to forward the closure to the client. This is
how HTTP 1.1 proposes to solve the issue. And it's fine IMHO,
because in HTTP/1.1 you always know the content-length of the POST
request. So by closing the client side when you detect the error
on the server side, you're just asking the client to try again.
That behaviour was necessary to implement keep-alive, because it's
very frequent that a connection expires on the server at the same
moment you're pushing a second request. So in this case, it will
be possible to retry a request if the server dies before it is
complete.

Regards,
Willy


Reply via email to