Mastering Load Balancing: From Random to Smooth Weighted Round‑Robin in Java
This article explains load‑balancing fundamentals, covering hardware vs. software devices, server‑side and client‑side balancing, and walks through common algorithms—random, weighted random, round‑robin, weighted and smooth weighted round‑robin, hash, consistent hash with virtual nodes, and least‑connection—each illustrated with Java code examples and diagrams.
Load Balancing Dimensions
From the perspective of load‑balancing devices, there are hardware (e.g., F5, Array) and software solutions (e.g., Nginx, LVS, Tengine). From the traffic flow view, there is server‑side balancing and client‑side balancing.
Algorithms
1. Random
public class Servers {
public List<String> list = new ArrayList<>() {{
add("192.168.1.1");
add("192.168.1.2");
add("192.168.1.3");
}};
}
public class FullRandom {
static Servers servers = new Servers();
static Random random = new Random();
public static String go() {
int number = random.nextInt(servers.list.size());
return servers.list.get(number);
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.println(go());
}
}
}Random selection distributes requests evenly only after many trials; it does not consider server capacity, so weighted random is often preferred.
2. Weighted Random
public class Servers {
public HashMap<String, Integer> map = new HashMap<>() {{
put("192.168.1.1", 2);
put("192.168.1.2", 7);
put("192.168.1.3", 1);
}};
}
public class WeightRandom {
static Servers servers = new Servers();
static Random random = new Random();
public static String go() {
List<String> ipList = new ArrayList<>();
for (var entry : servers.map.entrySet()) {
for (int i = 0; i < entry.getValue(); i++) {
ipList.add(entry.getKey());
}
}
int allWeight = servers.map.values().stream().mapToInt(i -> i).sum();
int number = random.nextInt(allWeight);
return ipList.get(number);
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.println(go());
}
}
}This method builds a list proportional to weights; it is simple but can waste memory when weights are large.
3. Round‑Robin
public class FullRound {
static Servers servers = new Servers();
static int index;
public static String go() {
if (index == servers.list.size()) {
index = 0;
}
return servers.list.get(index++);
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.println(go());
}
}
}Pure round‑robin treats all servers equally and suffers the same imbalance as random.
4. Weighted Round‑Robin
public class WeightRound {
static Servers servers = new Servers();
static int index;
public static String go() {
int allWeight = servers.map.values().stream().mapToInt(i -> i).sum();
int number = (index++) % allWeight;
for (var entry : servers.map.entrySet()) {
if (entry.getValue() > number) {
return entry.getKey();
}
number -= entry.getValue();
}
return "";
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.println(go());
}
}
}Weighted round‑robin avoids the memory issue of weighted random.
5. Smooth Weighted Round‑Robin
public class Server {
private int weight;
private int currentWeight;
private String ip;
// constructors, getters, setters omitted for brevity
}
public class Servers {
public HashMap<String, Server> serverMap = new HashMap<>() {{
put("192.168.1.1", new Server(5,5,"192.168.1.1"));
put("192.168.1.2", new Server(1,1,"192.168.1.2"));
put("192.168.1.3", new Server(1,1,"192.168.1.3"));
}};
}
public class SmoothWeightRound {
private static Servers servers = new Servers();
public static String go() {
Server maxWeightServer = null;
int allWeight = servers.serverMap.values().stream().mapToInt(Server::getWeight).sum();
for (var entry : servers.serverMap.entrySet()) {
Server cur = entry.getValue();
if (maxWeightServer == null || cur.getCurrentWeight() > maxWeightServer.getCurrentWeight()) {
maxWeightServer = cur;
}
}
maxWeightServer.setCurrentWeight(maxWeightServer.getCurrentWeight() - allWeight);
for (var entry : servers.serverMap.entrySet()) {
Server cur = entry.getValue();
cur.setCurrentWeight(cur.getCurrentWeight() + cur.getWeight());
}
return maxWeightServer.getIp();
}
public static void main(String[] args) {
for (int i = 0; i < 15; i++) {
System.out.println(go());
}
}
}This algorithm keeps a “current weight” for each server, producing a smooth distribution without sudden load spikes.
6. Hash
Hash‑based balancing maps a request attribute (e.g., user ID) to a hash value and selects the server whose position on a hash ring follows the value clockwise.
7. Consistent Hash with Virtual Nodes
To avoid “hash skew” where some servers own large hash intervals, each physical server is represented by multiple virtual nodes on the ring. A TreeMap stores the hash of each virtual node; the request is routed to the first node with a hash greater than the request’s hash, wrapping around if necessary.
private static String go(String client) {
int nodeCount = 20;
TreeMap<Integer, String> treeMap = new TreeMap<>();
for (String s : new Servers().list) {
for (int i = 0; i < nodeCount; i++) {
treeMap.put((s + "--server--" + i).hashCode(), s);
}
}
int clientHash = client.hashCode();
SortedMap<Integer, String> tail = treeMap.tailMap(clientHash);
Integer key = tail.isEmpty() ? treeMap.firstKey() : tail.firstKey();
return treeMap.get(key);
}Virtual nodes evenly distribute hash intervals, reducing load imbalance.
8. Minimum‑Load (Least‑Connection)
The least‑connection strategy picks the server with the fewest active requests. The article notes that a pure demonstration is omitted.
In practice, multiple algorithms are often combined: first select the least‑loaded servers, then apply weighted round‑robin, and finally fall back to random selection.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
