Replies: 1 comment
|
You can easily replace observatory / burstObservatory with your own type of testing. Just use Claude Code/Codex, it takes just few minutes. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Problem
Current balancer strategies (
leastPing,leastLoad,random,roundRobin) andobservatory/burstObservatoryjudge an outbound only by the RTT of a tiny probe request (e.g.generate_204). This misses the most common real-world failure: partial degradation. The path to a server shrinks to ~1 Mbit/s (ISP shaping, congested uplink, UDP loss), the 204 still arrives in 100–300 ms, the outbound is "alive and fast", and the user sits on it with frozen video.Real case (our service, Sep 2026): a user on a
leastPingbalancer watched short videos; the selected server kept answering probes every minute, but throughput collapsed. The balancer never switched. Diagnosis showed UDP buffer drops on the server (~1–5%) — RTT looked fine, bandwidth did not.A second issue:
leastPingsends every client to the geographically closest server, which is often the one with the weakest channel (in our case 14–84 Mbit/s vs 250 Mbit/s on another location). Nearest ≠ fastest.Related: #3186, #3299, #5908, sing-box#4397 (same idea for URLTest, no response yet).
Proposal
Add an optional throughput probe to the observatory and use it in the balancer.
burstObservatory.pingConfig(or a siblingthroughputConfig):Passive signal for the active outbound: Xray already counts bytes per outbound. If throughput on the active outbound drops sharply while there is demand (open connections waiting for data), trigger an immediate re-probe of the candidates instead of waiting for the next interval.
Strategy (new option on
leastLoad, or a newbestThroughputstrategy):maxRTT, failure rate <tolerance(existing);minMbps;Optional server hint (backward compatible): if the probe response contains a header like
X-Headroom-Mbps: 480, use it as a ranking weight. Absolute free bandwidth, not percent: a 200 Mbit/s server with 100 free is worse than a 1 Gbit/s server with 500 free. Servers that send nothing are treated as unknown/neutral — everything works as today.Optional: on switch, close existing connections through the degraded outbound (like sing-box
interrupt_exist_connections), otherwise they stay stuck untilconnIdle.Compatibility
All options are opt-in; with no new fields behaviour is unchanged. No protocol changes, works with any outbound type.
We can implement it and test on our servers if the direction is acceptable. Which shape do maintainers prefer: extend
leastLoador a separate strategy?All reactions