Backend Development 14 min read

Java Load Balancing Algorithms: Round Robin, Random, Source‑IP Hash, Weighted Round Robin, Weighted Random, and Least Connections

This article explains the concept of load balancing and provides Java implementations of several common algorithms—including Round Robin, Random, Source‑IP Hash, Weighted Round Robin, Weighted Random, and a discussion of Least Connections—highlighting their principles, advantages, drawbacks, and concurrency considerations.

Architecture Digest
Architecture Digest
Architecture Digest
Java Load Balancing Algorithms: Round Robin, Random, Source‑IP Hash, Weighted Round Robin, Weighted Random, and Least Connections

Load balancing distributes incoming requests across multiple servers to improve bandwidth, throughput, flexibility, and availability; it can be described as allocating external requests evenly among a symmetric server pool.

The article first defines load balancing and then presents a Java class IpMap that simulates a list of server IPs with associated weights.

import java.util.HashMap;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
public class IpMap {
    // Key: IP, Value: weight
    public static HashMap
serverWeightMap = new HashMap
();
    static {
        serverWeightMap.put("192.168.1.100", 1);
        serverWeightMap.put("192.168.1.101", 1);
        serverWeightMap.put("192.168.1.102", 4);
        serverWeightMap.put("192.168.1.103", 1);
        serverWeightMap.put("192.168.1.104", 1);
        serverWeightMap.put("192.168.1.105", 3);
        serverWeightMap.put("192.168.1.106", 1);
        serverWeightMap.put("192.168.1.107", 2);
        serverWeightMap.put("192.168.1.108", 1);
        serverWeightMap.put("192.168.1.109", 1);
        serverWeightMap.put("192.168.1.110", 1);
    }
}

Round Robin cycles through the server list sequentially, requiring no state tracking beyond a position counter; however, concurrency demands a synchronized block to protect the counter.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
class RoundRobin {
    private static Integer pos = 0;
    public static String getServer() {
        Map
serverMap = new HashMap
();
        serverMap.putAll(IpMap.serverWeightMap);
        Set keySet = serverMap.keySet();
        ArrayList keyList = new ArrayList();
        keyList.addAll(keySet);
        String server = null;
        synchronized (pos) {
            if (pos > keySet.size() - 1) pos = 0;
            server = (String) keyList.get(pos);
            pos++;
        }
        return server;
    }
}

Random selects a server by generating a random index within the server list, offering probabilistic distribution that approximates round robin as request volume grows.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
class Random {
    public static String getServer() {
        Map
serverMap = new HashMap
();
        serverMap.putAll(IpMap.serverWeightMap);
        Set keySet = serverMap.keySet();
        ArrayList keyList = new ArrayList();
        keyList.addAll(keySet);
        java.util.Random random = new java.util.Random();
        int randomPos = random.nextInt(keyList.size());
        return (String) keyList.get(randomPos);
    }
}

Source‑IP Hash hashes the client’s IP address and uses the modulus of the server list size to pick a server, ensuring the same client IP consistently maps to the same backend as long as the server pool remains unchanged.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
class Hash {
    public static String getServer() {
        Map
serverMap = new HashMap
();
        serverMap.putAll(IpMap.serverWeightMap);
        Set keySet = serverMap.keySet();
        ArrayList keyList = new ArrayList();
        keyList.addAll(keySet);
        String remoteIp = "127.0.0.1"; // example client IP
        int hashCode = remoteIp.hashCode();
        int serverPos = hashCode % keyList.size();
        return (String) keyList.get(serverPos);
    }
}

Weighted Round Robin expands the server list by replicating each server address according to its weight, then applies the round‑robin counter on this expanded list, giving higher‑weight servers more selections.

import java.util.*;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
class WeightRoundRobin {
    private static Integer pos;
    public static String getServer() {
        Map
serverMap = new HashMap
();
        serverMap.putAll(IpMap.serverWeightMap);
        Set keySet = serverMap.keySet();
        Iterator iterator = keySet.iterator();
        List serverList = new ArrayList();
        while (iterator.hasNext()) {
            String server = (String) iterator.next();
            int weight = serverMap.get(server);
            for (int i = 0; i < weight; i++) {
                serverList.add(server);
            }
        }
        String server = null;
        synchronized (pos) {
            if (pos > serverList.size() - 1) pos = 0;
            server = (String) serverList.get(pos);
            pos++;
        }
        return server;
    }
}

Weighted Random builds the same weighted server list as above but selects an entry using a random index, combining the concepts of weighted distribution and randomness.

import java.util.*;
/**
 * @author [email protected]
 * @date 二月 07, 2017
 */
class WeightRandom {
    public static String getServer() {
        Map
serverMap = new HashMap
();
        serverMap.putAll(IpMap.serverWeightMap);
        Set keySet = serverMap.keySet();
        Iterator iterator = keySet.iterator();
        List serverList = new ArrayList();
        while (iterator.hasNext()) {
            String server = (String) iterator.next();
            int weight = serverMap.get(server);
            for (int i = 0; i < weight; i++) {
                serverList.add(server);
            }
        }
        java.util.Random random = new java.util.Random();
        int randomPos = random.nextInt(serverList.size());
        return (String) serverList.get(randomPos);
    }
}

The article also mentions Least Connections , an adaptive method that selects the server with the fewest active connections, noting that request‑count balancing does not always reflect true load and that connection‑aware routing can improve resource utilization, though its implementation is more complex and is not detailed here.

backendJavaload balancinghashRound RobinRandomWeighted
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.