mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-20 22:01:49 -04:00
[MEDIUM] add a turn-around state of one second after a connection failure
Several users have complained that when haproxy gets a connection failure due to an active reject from a server, it immediately retries, often leading to the same situation being repeated until the retry counter reaches zero. Now if a connection error shows up, a turn-around state of 1 second is applied before retrying. This is performed by faking a connection timeout in order not to touch much code. However, a cleaner method would involve an extra state.
This commit is contained in:
parent
25b501a6b1
commit
541b5c24ca
2 changed files with 31 additions and 11 deletions
|
|
@ -49,7 +49,7 @@
|
|||
#define SN_SELF_GEN 0x00000040 /* the proxy generates data for the client (eg: stats) */
|
||||
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
||||
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
|
||||
/* unused: 0x00000200 */
|
||||
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
|
||||
/* unused: 0x00000400 */
|
||||
/* unused: 0x00000800 */
|
||||
|
||||
|
|
|
|||
|
|
@ -2488,18 +2488,38 @@ int process_srv(struct session *t)
|
|||
/* timeout, asynchronous connect error or first write error */
|
||||
//fprintf(stderr,"2: c=%d, s=%d\n", c, s);
|
||||
|
||||
fd_delete(t->srv_fd);
|
||||
if (t->srv)
|
||||
t->srv->cur_sess--;
|
||||
if (t->flags & SN_CONN_TAR) {
|
||||
/* We are doing a turn-around waiting for a new connection attempt. */
|
||||
if (!tv_isle(&req->cex, &now))
|
||||
return 0;
|
||||
t->flags &= ~SN_CONN_TAR;
|
||||
}
|
||||
else {
|
||||
fd_delete(t->srv_fd);
|
||||
if (t->srv)
|
||||
t->srv->cur_sess--;
|
||||
|
||||
if (!(req->flags & BF_WRITE_STATUS))
|
||||
conn_err = SN_ERR_SRVTO; // it was a connect timeout.
|
||||
else
|
||||
conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
|
||||
if (!(req->flags & BF_WRITE_STATUS))
|
||||
conn_err = SN_ERR_SRVTO; // it was a connect timeout.
|
||||
else
|
||||
conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
|
||||
|
||||
/* ensure that we have enough retries left */
|
||||
if (srv_count_retry_down(t, conn_err))
|
||||
return 1;
|
||||
/* ensure that we have enough retries left */
|
||||
if (srv_count_retry_down(t, conn_err))
|
||||
return 1;
|
||||
|
||||
if (req->flags & BF_WRITE_ERROR) {
|
||||
/* we encountered an immediate connection error, and we
|
||||
* will have to retry connecting to the same server, most
|
||||
* likely leading to the same result. To avoid this, we
|
||||
* fake a connection timeout to retry after a turn-around
|
||||
* time of 1 second. We will wait in the previous if block.
|
||||
*/
|
||||
t->flags |= SN_CONN_TAR;
|
||||
tv_ms_add(&req->cex, &now, 1000);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->srv && t->conn_retries == 0 && t->be->options & PR_O_REDISP) {
|
||||
/* We're on our last chance, and the REDISP option was specified.
|
||||
|
|
|
|||
Loading…
Reference in a new issue