负载均衡的简单实现
常见的负载均衡算法有:随机、轮询、哈希,带权重的随机和轮询等。这里举例简单说一下怎么实现这些算法:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; public class Weight { // 4台服务器集群 private static final String IP1 = "110.11.10.1"; private static final String IP2 = "110.11.10.2"; private static final String IP3 = "110.11.10.3"; private static final String IP4 = "110.11.10.4"; // 4台请求机器 private static final String REQUEST_IP1 = "192.168.1.11"; private static final String REQUEST_IP2 = "110.1.33.22"; private static final String REQUEST_IP3 = "172.195.105.33"; private static final String REQUEST_IP4 = "10.166.175.174"; /** * 负载均衡之随机 */ private static void randomLB() { System.out.println("随机负载均衡开始:"); // 根据已有机器,构造一个集群列表 List randomIps = buildIps(); if (randomIps.size() == 0) { System.out.println("没有机器可用。"); return; } // 模拟10个请求到来 Random random = new Random(); for (int i = 0; i < 10; i++) { System.out.printf("第 %2d 个请求,由服务器 %s 接收\n", i, randomIps.get(random.nextInt(randomIps.size()))); } } /** * 负载均衡之轮询 */ private static void roundRibbonLB() { System.out.println("轮询负载均衡开始:"); // 根据已有机器,构造一个集群列表 List roundRibbonIps = buildIps(); if (roundRibbonIps.size() == 0) { System.out.println("没有机器可用。"); return; } // 模拟10个请求到来 int index = 0; for (int i = 0; i < 10; i++) { if (i % roundRibbonIps.size() == 0) { index = 0; } System.out.printf("第 %2d 个请求,由服务器 %s 接收\n", i, roundRibbonIps.get(index++)); } } /** * 负载均衡之哈希 */ private static void hashLB() { System.out.println("哈希负载均衡开始:"); // 构造请求列表,模拟10个请求 List hashRequestIps = buildRequestIps(); // 根据已有机器,构造一个集群列表 List serverIps = buildIps(); if (hashRequestIps.size() == 0 || serverIps.size() == 0) { System.out.println("没有请求机器或服务器。"); return; } // 模拟10个请求到来 int index = 0; // for (int i = 0; i < hashRequestIps.size(); i++) { // 对hashcode结果取绝对值,再hash一下,再取模 index = Math.abs(hashRequestIps.get(i).hashCode()) % serverIps.size(); System.out.printf("第 %2d 个请求,由服务器 %s 接收\n", i, serverIps.get(index)); } } /** * 负载均衡之随机+权重,先按权重排好队,权重如1:2:3:4 */ private static void randomWeightLB() { System.out.println("随机带权重负载均衡开始:"); // 构建权重服务器列表 List<String> weightList = buildWeightList(); if (weightList.size() == 0) { System.out.println("没有机器可用。"); return; } // 模拟30个请求到来 Random random = new Random(); int index = 0; for (int i = 0; i < 30; i++) { index = random.nextInt(weightList.size()); System.out.printf("第 %2d 个请求,由服务器 %s 接收\n", i, weightList.get(index)); } } /** * 负载均衡之轮询+权重,先按权重排好队,权重如1:2:3:4 */ private static void roundRibbonWeightLB() { System.out.println("轮询带权重负载均衡开始:"); // 根据已有服务器,构造服务器权重列表 List<String> weightList = buildWeightList(); if (weightList.size() == 0) { System.out.println("没有机器可用。"); return; } // 模拟30个请求到来 int index = 0; for (int i = 0; i < 30; i++) { // 每当队列走完一圈时,再从头来过 if (i % weightList.size() == 0) { index = 0; } System.out.printf("第 %2d 个请求,由服务器 %s 接收\n", i, weightList.get(index++)); } } /** * 构建服务器列表 * * @return */ private static List<String> buildIps() { return new ArrayList(buildIpWeightMap().keySet()); } /** * 构建请求的ip列表 * * @return */ private static List buildRequestIps() { List hashIps = new ArrayList(); hashIps.add(IP1); hashIps.add(IP2); hashIps.add(IP3); hashIps.add(IP4); hashIps.add(REQUEST_IP1); hashIps.add(REQUEST_IP2); hashIps.add(REQUEST_IP3); hashIps.add(REQUEST_IP4); hashIps.add(IP1); hashIps.add(REQUEST_IP2); return hashIps; } /** * 集群服务器按权重排队,权重按1:2:3:4来 * * @return */ private static List<String> buildWeightList() { // 给ip们分配权重,key为服务器ip,value为权重值 Map<String, Integer> weightIps = buildIpWeightMap(); // 排队 List<String> ips = new ArrayList<>(); for (Map.Entry<String, Integer> ip : weightIps.entrySet()) { for (int i = 0; i < ip.getValue(); i++) { ips.add(ip.getKey()); } } return ips; } /** * 构造服务器和他们的权重 * * @return */ private static Map<String, Integer> buildIpWeightMap() { Map<String, Integer> weightIps = new HashMap<>(); weightIps.put(IP1, 1); weightIps.put(IP2, 2); weightIps.put(IP3, 3); weightIps.put(IP4, 4); return weightIps; } public static void main(String[] args) { randomLB(); roundRibbonLB(); hashLB(); randomWeightLB(); roundRibbonWeightLB(); } }
运行结果:
随机负载均衡开始: 第 0 个请求,由服务器 110.11.10.2 接收 第 1 个请求,由服务器 110.11.10.1 接收 第 2 个请求,由服务器 110.11.10.2 接收 第 3 个请求,由服务器 110.11.10.2 接收 第 4 个请求,由服务器 110.11.10.1 接收 第 5 个请求,由服务器 110.11.10.1 接收 第 6 个请求,由服务器 110.11.10.2 接收 第 7 个请求,由服务器 110.11.10.3 接收 第 8 个请求,由服务器 110.11.10.3 接收 第 9 个请求,由服务器 110.11.10.3 接收 轮询负载均衡开始: 第 0 个请求,由服务器 110.11.10.4 接收 第 1 个请求,由服务器 110.11.10.3 接收 第 2 个请求,由服务器 110.11.10.2 接收 第 3 个请求,由服务器 110.11.10.1 接收 第 4 个请求,由服务器 110.11.10.4 接收 第 5 个请求,由服务器 110.11.10.3 接收 第 6 个请求,由服务器 110.11.10.2 接收 第 7 个请求,由服务器 110.11.10.1 接收 第 8 个请求,由服务器 110.11.10.4 接收 第 9 个请求,由服务器 110.11.10.3 接收 哈希负载均衡开始: 第 0 个请求,由服务器 110.11.10.2 接收 第 1 个请求,由服务器 110.11.10.1 接收 第 2 个请求,由服务器 110.11.10.4 接收 第 3 个请求,由服务器 110.11.10.3 接收 第 4 个请求,由服务器 110.11.10.4 接收 第 5 个请求,由服务器 110.11.10.1 接收 第 6 个请求,由服务器 110.11.10.3 接收 第 7 个请求,由服务器 110.11.10.3 接收 第 8 个请求,由服务器 110.11.10.2 接收 第 9 个请求,由服务器 110.11.10.1 接收 随机带权重负载均衡开始: 第 0 个请求,由服务器 110.11.10.3 接收 第 1 个请求,由服务器 110.11.10.3 接收 第 2 个请求,由服务器 110.11.10.2 接收 第 3 个请求,由服务器 110.11.10.2 接收 第 4 个请求,由服务器 110.11.10.3 接收 第 5 个请求,由服务器 110.11.10.4 接收 第 6 个请求,由服务器 110.11.10.4 接收 第 7 个请求,由服务器 110.11.10.4 接收 第 8 个请求,由服务器 110.11.10.4 接收 第 9 个请求,由服务器 110.11.10.3 接收 第 10 个请求,由服务器 110.11.10.2 接收 第 11 个请求,由服务器 110.11.10.4 接收 第 12 个请求,由服务器 110.11.10.4 接收 第 13 个请求,由服务器 110.11.10.3 接收 第 14 个请求,由服务器 110.11.10.2 接收 第 15 个请求,由服务器 110.11.10.2 接收 第 16 个请求,由服务器 110.11.10.3 接收 第 17 个请求,由服务器 110.11.10.4 接收 第 18 个请求,由服务器 110.11.10.4 接收 第 19 个请求,由服务器 110.11.10.2 接收 第 20 个请求,由服务器 110.11.10.1 接收 第 21 个请求,由服务器 110.11.10.4 接收 第 22 个请求,由服务器 110.11.10.3 接收 第 23 个请求,由服务器 110.11.10.4 接收 第 24 个请求,由服务器 110.11.10.4 接收 第 25 个请求,由服务器 110.11.10.4 接收 第 26 个请求,由服务器 110.11.10.2 接收 第 27 个请求,由服务器 110.11.10.4 接收 第 28 个请求,由服务器 110.11.10.2 接收 第 29 个请求,由服务器 110.11.10.4 接收 轮询带权重负载均衡开始: 第 0 个请求,由服务器 110.11.10.4 接收 第 1 个请求,由服务器 110.11.10.4 接收 第 2 个请求,由服务器 110.11.10.4 接收 第 3 个请求,由服务器 110.11.10.4 接收 第 4 个请求,由服务器 110.11.10.3 接收 第 5 个请求,由服务器 110.11.10.3 接收 第 6 个请求,由服务器 110.11.10.3 接收 第 7 个请求,由服务器 110.11.10.2 接收 第 8 个请求,由服务器 110.11.10.2 接收 第 9 个请求,由服务器 110.11.10.1 接收 第 10 个请求,由服务器 110.11.10.4 接收 第 11 个请求,由服务器 110.11.10.4 接收 第 12 个请求,由服务器 110.11.10.4 接收 第 13 个请求,由服务器 110.11.10.4 接收 第 14 个请求,由服务器 110.11.10.3 接收 第 15 个请求,由服务器 110.11.10.3 接收 第 16 个请求,由服务器 110.11.10.3 接收 第 17 个请求,由服务器 110.11.10.2 接收 第 18 个请求,由服务器 110.11.10.2 接收 第 19 个请求,由服务器 110.11.10.1 接收 第 20 个请求,由服务器 110.11.10.4 接收 第 21 个请求,由服务器 110.11.10.4 接收 第 22 个请求,由服务器 110.11.10.4 接收 第 23 个请求,由服务器 110.11.10.4 接收 第 24 个请求,由服务器 110.11.10.3 接收 第 25 个请求,由服务器 110.11.10.3 接收 第 26 个请求,由服务器 110.11.10.3 接收 第 27 个请求,由服务器 110.11.10.2 接收 第 28 个请求,由服务器 110.11.10.2 接收 第 29 个请求,由服务器 110.11.10.1 接收