MINOR: leastconn: take the queue length into account when queuing servers

When servers are queued into the leastconn tree, it's important to also
consider their queue length. There could be some servers with lots of
queued requests that we don't want to hammer with extra connections. In
order not to add extra stress to the LB algorithm, we don't update the
value when adding to the queue, only when updating the connection count
(i.e. picking from the queue or releasing a connection). This will be
sufficient to significantly improve the fairness in such situations.
This commit is contained in:
Willy Tarreau 2020-10-22 17:41:45 +02:00
parent 96bca33d75
commit 8c855f6cff
2 changed files with 6 additions and 2 deletions

View File

@ -3205,7 +3205,9 @@ balance url_param <param> [check_post]
expected, such as LDAP, SQL, TSE, etc... but is not very well expected, such as LDAP, SQL, TSE, etc... but is not very well
suited for protocols using short sessions such as HTTP. This suited for protocols using short sessions such as HTTP. This
algorithm is dynamic, which means that server weights may be algorithm is dynamic, which means that server weights may be
adjusted on the fly for slow starts for instance. adjusted on the fly for slow starts for instance. It will
also consider the number of queued connections in addition to
the established ones in order to minimize queuing.
first The first server with available connection slots receives the first The first server with available connection slots receives the
connection. The servers are chosen from the lowest numeric connection. The servers are chosen from the lowest numeric

View File

@ -51,7 +51,9 @@ static inline void fwlc_dequeue_srv(struct server *s)
*/ */
static inline void fwlc_queue_srv(struct server *s) static inline void fwlc_queue_srv(struct server *s)
{ {
s->lb_node.key = s->served ? (s->served + 1) * SRV_EWGHT_MAX / s->next_eweight : 0; unsigned int inflight = s->served + s->nbpend;
s->lb_node.key = inflight ? (inflight + 1) * SRV_EWGHT_MAX / s->next_eweight : 0;
eb32_insert(s->lb_tree, &s->lb_node); eb32_insert(s->lb_tree, &s->lb_node);
} }