mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 06:11:32 +02:00
When haproxy decides that session needs to be redispatched it chose a server, but there is no guarantee for it to be a different one. So, it often happens that selected server is exactly the same that it was previously, so a client ends up with a 503 error anyway, especially when one sever has much bigger weight than others. Changes from the previous version: - drop stupid and unnecessary SN_DIRECT changes - assign_server(): use srvtoavoid to keep the old server and clear s->srv so SRV_STATUS_NOSRV guarantees that t->srv == NULL (again) and get_server_rr_with_conns has chances to work (previously we were passing a NULL here) - srv_redispatch_connect(): remove t->srv->cum_sess and t->srv->failed_conns incrementing as t->srv was guaranteed to be NULL - add avoididx to get_server_rr_with_conns. I hope I correctly understand this code. - fix http_flush_cookie_flags() and move it to assign_server_and_queue() directly. The code here was supposed to set CK_DOWN and clear CK_VALID, but: (TX_CK_VALID | TX_CK_DOWN) == TX_CK_VALID == TX_CK_MASK so: if ((txn->flags & TX_CK_MASK) == TX_CK_VALID) txn->flags ^= (TX_CK_VALID | TX_CK_DOWN); was really a: if ((txn->flags & TX_CK_MASK) == TX_CK_VALID) txn->flags &= TX_CK_VALID Now haproxy logs "--DI" after redispatching connection. - defer srv->redispatches++ and s->be->redispatches++ so there are called only if a conenction was redispatched, not only supposed to. - don't increment lbconn if redispatcher selected the same sarver - don't count unsuccessfully redispatched connections as redispatched connections - don't count redispatched connections as errors, so: - the number of connections effectively served by a server is: srv->cum_sess - srv->failed_conns - srv->retries - srv->redispatches and SUM(servers->failed_conns) == be->failed_conns - requires the "Don't increment server connections too much + fix retries" patch - needs little more testing and probably some discussion so reverting to the RFC state Tests #1: retries 4 redispatch i) 1 server(s): b (wght=1, down) b) sessions=5, lbtot=1, err_conn=1, retr=4, redis=0 -> request failed ii) server(s): b (wght=1, down), u (wght=1, down) b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1 u) sessions=1, lbtot=1, err_conn=1, retr=0, redis=0 -> request FAILED iii) 2 server(s): b (wght=1, down), u (wght=1, up) b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1 u) sessions=1, lbtot=1, err_conn=0, retr=0, redis=0 -> request OK iv) 2 server(s): b (wght=100, down), u (wght=1, up) b) sessions=4, lbtot=1, err_conn=0, retr=3, redis=1 u) sessions=1, lbtot=1, err_conn=0, retr=0, redis=0 -> request OK v) 1 server(s): b (down for first 4 SYNS) b) sessions=5, lbtot=1, err_conn=0, retr=4, redis=0 -> request OK Tests #2: retries 4 i) 1 server(s): b (down) b) sessions=5, lbtot=1, err_conn=1, retr=4, redis=0 -> request FAILED
93 lines
3.8 KiB
C
93 lines
3.8 KiB
C
/*
|
|
include/proto/proto_http.h
|
|
This file contains HTTP protocol definitions.
|
|
|
|
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation, version 2.1
|
|
exclusively.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifndef _PROTO_PROTO_HTTP_H
|
|
#define _PROTO_PROTO_HTTP_H
|
|
|
|
#include <common/config.h>
|
|
#include <types/proto_http.h>
|
|
#include <types/session.h>
|
|
#include <types/task.h>
|
|
|
|
/*
|
|
* some macros used for the request parsing.
|
|
* from RFC2616:
|
|
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
|
* SEP = one of the 17 defined separators or SP or HT
|
|
* LWS = CR, LF, SP or HT
|
|
* SPHT = SP or HT. Use this macro and not a boolean expression for best speed.
|
|
* CRLF = CR or LF. Use this macro and not a boolean expression for best speed.
|
|
* token = any CHAR except CTL or SEP. Use this macro and not a boolean expression for best speed.
|
|
*
|
|
* added for ease of use:
|
|
* ver_token = 'H', 'P', 'T', '/', '.', and digits.
|
|
*/
|
|
|
|
extern const char http_is_ctl[256];
|
|
extern const char http_is_sep[256];
|
|
extern const char http_is_lws[256];
|
|
extern const char http_is_spht[256];
|
|
extern const char http_is_crlf[256];
|
|
extern const char http_is_token[256];
|
|
extern const char http_is_ver_token[256];
|
|
|
|
#define HTTP_IS_CTL(x) (http_is_ctl[(unsigned char)(x)])
|
|
#define HTTP_IS_SEP(x) (http_is_sep[(unsigned char)(x)])
|
|
#define HTTP_IS_LWS(x) (http_is_lws[(unsigned char)(x)])
|
|
#define HTTP_IS_SPHT(x) (http_is_spht[(unsigned char)(x)])
|
|
#define HTTP_IS_CRLF(x) (http_is_crlf[(unsigned char)(x)])
|
|
#define HTTP_IS_TOKEN(x) (http_is_token[(unsigned char)(x)])
|
|
#define HTTP_IS_VER_TOKEN(x) (http_is_ver_token[(unsigned char)(x)])
|
|
|
|
int event_accept(int fd);
|
|
void process_session(struct task *t, struct timeval *next);
|
|
int process_cli(struct session *t);
|
|
int process_srv(struct session *t);
|
|
|
|
void client_retnclose(struct session *s, const struct chunk *msg);
|
|
void client_return(struct session *s, const struct chunk *msg);
|
|
void srv_close_with_err(struct session *t, int err, int finst,
|
|
int status, const struct chunk *msg);
|
|
|
|
int produce_content(struct session *s);
|
|
int produce_content_stats(struct session *s);
|
|
int produce_content_stats_proxy(struct session *s, struct proxy *px);
|
|
void debug_hdr(const char *dir, struct session *t, const char *start, const char *end);
|
|
void get_srv_from_appsession(struct session *t, const char *begin, int len);
|
|
int apply_filter_to_req_headers(struct session *t, struct buffer *req, struct hdr_exp *exp);
|
|
int apply_filter_to_req_line(struct session *t, struct buffer *req, struct hdr_exp *exp);
|
|
int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_exp *exp);
|
|
int apply_filters_to_response(struct session *t, struct buffer *rtr, struct hdr_exp *exp);
|
|
void manage_client_side_cookies(struct session *t, struct buffer *req);
|
|
void manage_server_side_cookies(struct session *t, struct buffer *rtr);
|
|
void check_response_for_cacheability(struct session *t, struct buffer *rtr);
|
|
int stats_check_uri_auth(struct session *t, struct proxy *backend);
|
|
void init_proto_http();
|
|
|
|
#endif /* _PROTO_PROTO_HTTP_H */
|
|
|
|
/*
|
|
* Local variables:
|
|
* c-indent-level: 8
|
|
* c-basic-offset: 8
|
|
* End:
|
|
*/
|