Repository navigation
Description
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
RoundRobinLoadBalancer sums effective upstream weights in an int, although each upstream weight is itself an int and the running score is an AtomicLong. When the sum overflows, the selected upstream's score is adjusted using the wrapped total. Traffic can remain pinned to one upstream instead of following the configured weights.
For example, two enabled upstreams with weights 1_500_000_000 and 1_000_000_000 should split 30 selections as 18/12. On current master they split 30/0. Two upstreams both weighted Integer.MAX_VALUE split 30/0 instead of 15/15.
This is a large-weight arithmetic boundary case, reproduced locally rather than a report of a production incident. The Admin discovery DTO accepts an integer weight without an upper-bound annotation, and the Divide discovery handler forwards the weight into Upstream.
Expected Behavior
Positive weights should preserve their relative proportions even when their combined value exceeds Integer.MAX_VALUE. Accumulation and subtraction must not narrow the total back to int.
Steps To Reproduce
Run the following with the loadbalancer classes:
Upstream first = Upstream.builder().url("first:8080")
.weight(1_500_000_000).status(true).build();
Upstream second = Upstream.builder().url("second:8080")
.weight(1_000_000_000).status(true).build();
RoundRobinLoadBalancer balancer = new RoundRobinLoadBalancer();
Map<String, Integer> counts = new HashMap<>();
for (int i = 0; i < 30; i++) {
Upstream selected = balancer.select(List.of(first, second), new LoadBalanceData());
counts.merge(selected.getUrl(), 1, Integer::sum);
}
System.out.println(counts);Actual: {first:8080=30}. Expected: 18 selections for the first upstream and 12 for the second.
Environment
- ShenYu: `2.7.3-SNAPSHOT`, master `d7e8282b44abe279f9a34602498342af0038976d`.
- Java: OpenJDK 21.0.13; repository Maven wrapper 3.6.3.
- Regression test: `RoundRobinLoadBalanceTest#testLargeWeightsPreserveDistribution`.Debug logs
No response
Anything else?
In RoundRobinLoadBalancer.java, both totalWeight and WeightedRoundRobin.sel's argument use int.
With the regression test added and production code unchanged, the targeted Maven run executes 9 tests with 3 failures: 3:2, 1:2, and equal maximum weights. The cases below the overflow boundary and at a combined weight of 2^31 remain useful compatibility controls.
A focused fix can carry the total as long through accumulation and subtraction, without changing individual weight configuration or warmup behavior.
After the fix: ./mvnw -B -ntp -pl shenyu-loadbalancer -am clean verify -Dmaven.javadoc.skip=true passed (786 tests, 0 failures/errors, 4 skipped), including Checkstyle and Apache RAT. The local test JVM was started with the Byte Buddy agent because this environment cannot attach it dynamically.
Activity