public Upstream next() {
        if (upstreamStates.isEmpty()) {
            return null;
        }

        List<Upstream> availableUpstreams = upstreamStates.stream().filter(UpstreamState::isUpstreamAvailable)
                .map(UpstreamState::getUpstream).toList();
        if (availableUpstreams.isEmpty()) {
            return null;
        }
        if (availableUpstreams.size() == 1) {
            return availableUpstreams.get(0);
        }
        int total = availableUpstreams.stream().map(Upstream::getWeight).reduce(0, Integer::sum);
        int random = generator.nextInt(total);
        int current = 0;

        Upstream result = null;

        for (Upstream upstream : availableUpstreams) {
            current += upstream.getWeight();
            if (current > random) {
                result = upstream;
                break;
            }
        }

        return result;
    }
Load balancer distributes load in the proportion of probability of upstream weights.
The higher upstream weight, the higher probability the upstream takes more load.
server/src/main/java/com/epam/aidial/core/server/upstream/RandomizedWeightedBalancer.java