Hi,

consistent-hash and "balance random" load balancing pick a natural
target server on the ring, then silently fall back to another one
when that target can't be used: a previous connect attempt failed and
"option redispatch" kicked in, "hash-balance-factor" judged it over
its load quota, or "hash-preserve-affinity maxconn/maxqueue" judged it
saturated. This is a signal we want to track as a standing operational
metric.

This series adds that visibility: a single "lbbypass" stats counter
(incremented on both the bypassed server and the backend, mirroring
the existing retries/redispatches pattern) plus a per-request
"txn.lb_bypass_reason" sample fetch usable in log-format/ACLs. Full
rationale and implementation details are in patch 1's commit message;
patch 2 adds reg-test coverage for both.

Sending as RFC because this touches chash_get_server_hash() and 8
call sites in backend.c, and I'd like feedback before polishing
further, specifically on:

  - Shape: chash_get_server_hash() and the get_server_*() wrappers
    each gain a trailing "enum lb_bypass_reason *reason_out"
    out-parameter. Is this the preferred way to surface this, or
    would you rather see it handled differently (e.g. stashed
    directly on the stream from within lb_chash.c, or exposed via
    the existing trace/term_events mechanism instead of a new
    parameter threaded through 8 call sites)?

  - Scope: this intentionally does NOT detect a naive target being
    skipped for being in drain mode or marked unhealthy, since such
    servers are removed from the ring entirely and there's nothing
    left to compare against without a second, always-populated
    shadow ring. Is landing the cheaply-detectable reasons now,
    with drain/unhealthy detection as a documented follow-up,
    reasonable, or should that gap block this series?

  - Counter granularity: one aggregate "lbbypass" counter rather
    than one per reason, matching an explicit request to keep this
    simple. Would a per-reason breakdown be preferred instead?

  - Naming: "lbbypass" for the stats column, "txn.lb_bypass_reason"
    for the sample fetch, and "redispatch" / "hash-balance-factor" /
    "preserve-affinity-maxconn" / "preserve-affinity-maxqueue" for
    its possible values. Open to better names for any of these.

Built and tested on macOS/arm64 (TARGET=osx); reg-tests pass against
a locally built vtest, including the two new ones and the existing
reg-tests/balance/ and reg-tests/log/ suites.

Thanks for taking a look.

David Birdsong (2):
  MEDIUM: backend: report consistent-hash LB bypass reason
  REGTEST: balance: add coverage for lb_bypass counter and reason

 doc/configuration.txt                         |  27 ++++-
 doc/management.txt                            |   3 +
 include/haproxy/backend-t.h                   |  14 +++
 include/haproxy/backend.h                     |  24 +++--
 include/haproxy/counters-t.h                  |   1 +
 include/haproxy/lb_chash.h                    |   3 +-
 include/haproxy/stats-file-t.h                |   2 +-
 include/haproxy/stats-t.h                     |   1 +
 include/haproxy/stream-t.h                    |   1 +
 .../balance/balance-hash-bypass-maxconn.vtc   | 101 ++++++++++++++++++
 .../balance-hash-bypass-redispatch.vtc        |  71 ++++++++++++
 src/backend.c                                 |  79 +++++++++-----
 src/lb_chash.c                                |  46 +++++++-
 src/log.c                                     |   2 +-
 src/stats-proxy.c                             |   1 +
 src/stream.c                                  |  27 +++++
 16 files changed, 360 insertions(+), 43 deletions(-)
 create mode 100644 reg-tests/balance/balance-hash-bypass-maxconn.vtc
 create mode 100644 reg-tests/balance/balance-hash-bypass-redispatch.vtc

-- 
2.52.0



Reply via email to