mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
BUG/MAJOR: connection: fix server used_conns with H2 + reuse safe
By default, backend connections are accounted by the server. This allows to determine the number of idle connections to keep. A backend connection can also be marked as private to prevent its reuse. It is thus removed from server lists into the session list. As such, a private connection is not accounted into server : conn_set_private() uses srv_release_conn() to ensure this. When using HTTP/2 on backend side with default http-reuse safe, the above principle are mixed. Indeed, when a connection is first used, or switches from idle to used, it is moved into the session list but it is not flagged as private. This is done to prevent its sharing by different clients to prevent head-of-line blocking issue. When all streams are closed, the connection becomes idle again and is reinserted in the server list. This has been introduced by the following patch : 0d21deaded1a4bbd1e1700ab8386af1f1441ea73 MEDIUM: backend: add reused conn to sess if mux marked as HOL blocking When freeing a backend connection, special care is taken to ensure server used counter is decremented. This is implemented into conn_backend_deinit(). However, this function does this only if the connection is not present in a session list. This is valid for private connections. However, if a connection is non-private and present only temporarily into a session list, the decrement operation won't be executed despite the connection being accounted by the server. This bug has several impacts. The server used counter won't be able to reach its initial null value, even when all its connections are closed. This can result in a wrong estimation of necessary idle connections, which may cause unnecessary new connection usage. Also, this will prevent definitely the server from being removed via "delete server" CLI command. This should be backported up to 2.4. Note that conn_backend_deinit() was introduced in 2.9. For lesser versions, the change should be done directly into conn_free().
This commit is contained in:
parent
fd3ce173aa
commit
87b96cf3a5
@ -511,12 +511,12 @@ static int conn_backend_init(struct connection *conn)
|
||||
*/
|
||||
static void conn_backend_deinit(struct connection *conn)
|
||||
{
|
||||
/* If the connection is owned by the session, remove it from its list
|
||||
*/
|
||||
if (conn_is_back(conn) && LIST_INLIST(&conn->sess_el)) {
|
||||
/* If the connection is owned by the session, remove it from its list. */
|
||||
if (LIST_INLIST(&conn->sess_el))
|
||||
session_unown_conn(conn->owner, conn);
|
||||
}
|
||||
else if (!(conn->flags & CO_FL_PRIVATE)) {
|
||||
|
||||
/* If the connection is not private, it is accounted by the server. */
|
||||
if (!(conn->flags & CO_FL_PRIVATE)) {
|
||||
if (obj_type(conn->target) == OBJ_TYPE_SERVER)
|
||||
srv_release_conn(__objt_server(conn->target), conn);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user