Five ways to choose a backend. Round-robin, weighted round-robin when your machines are not the same size, least-connections, random, and IP hash when a visitor needs to keep landing on the same server.
Failing servers are skipped, not served. Background probes check each backend on an interval. A server that fails enough probes is taken out of rotation and put back when it recovers. A per-backend circuit breaker does the same for failures your probes never see.
Retries, but only where they are safe. A request that fails on a connection error is tried again on another backend — but only if the method is one that can be repeated without side effects. A POST is never retried for you.
A server list that can change. Read it from DNS or from a JSON file that another system rewrites, and Haribon picks up additions and removals while it runs.
More than one Haribon. Replicas compare notes over UDP, so a server one of them cannot reach is skipped by all of them. There is no separate coordination service to run.
You can see what is happening. Prometheus metrics, per-request logs, and an optional feed to Loki, Elasticsearch, or Fluent Bit.