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

