diff --git a/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/AbstractArrayWeightRandomLoadBalance.java b/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/AbstractArrayWeightRandomLoadBalance.java index 3944f29417..f0c8d0ebee 100644 --- a/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/AbstractArrayWeightRandomLoadBalance.java +++ b/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/AbstractArrayWeightRandomLoadBalance.java @@ -10,7 +10,6 @@ */ import java.util.List; -import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.collections4.CollectionUtils; @@ -18,6 +17,8 @@ import com.netflix.loadbalancer.Server; public abstract class AbstractArrayWeightRandomLoadBalance implements WeightRandomLoadBalance { + private ArrayWeightRandom arrayWeightRandom = new ArrayWeightRandom(); + @Override public Server choose(List serverList, T t) { if (CollectionUtils.isEmpty(serverList)) { @@ -30,36 +31,8 @@ public Server choose(List serverList, T t) { weights[i] = getWeight(server, t); } - int index = getIndex(weights); + int index = arrayWeightRandom.getIndex(weights); return serverList.get(index); } - - private int getIndex(int[] weights) { - // 次序号/权重区间值 - int[][] weightHolder = new int[weights.length][2]; - // 总权重 - int totalWeight = 0; - // 赋值次序号和区间值累加的数组值,从小到大排列 - // 例如,对于权重分别为20,40, 60的三个服务,将形成[0, 20),[20, 60),[60, 120]三个区间 - for (int i = 0; i < weights.length; i++) { - if (weights[i] <= 0) { - continue; - } - - totalWeight += weights[i]; - weightHolder[i][0] = i; - weightHolder[i][1] = totalWeight; - } - - // 获取介于0(含)和n(不含)伪随机,均匀分布的int值 - int hitWeight = ThreadLocalRandom.current().nextInt(totalWeight) + 1; // [1, totalWeight) - for (int i = 0; i < weightHolder.length; i++) { - if (hitWeight <= weightHolder[i][1]) { - return weightHolder[i][0]; - } - } - - return weightHolder[0][0]; - } } \ No newline at end of file diff --git a/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/ArrayWeightRandom.java b/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/ArrayWeightRandom.java new file mode 100644 index 0000000000..8b06092e21 --- /dev/null +++ b/discovery-plugin-framework/src/main/java/com/nepxion/discovery/plugin/framework/loadbalance/weight/ArrayWeightRandom.java @@ -0,0 +1,42 @@ +package com.nepxion.discovery.plugin.framework.loadbalance.weight; + +/** + *

Title: Nepxion Discovery

+ *

Description: Nepxion Discovery

+ *

Copyright: Copyright (c) 2017-2050

+ *

Company: Nepxion

+ * @author Haojun Ren + * @version 1.0 + */ + +import java.util.concurrent.ThreadLocalRandom; + +public class ArrayWeightRandom { + public int getIndex(int[] weights) { + // 次序号/权重区间值 + int[][] weightHolder = new int[weights.length][2]; + // 总权重 + int totalWeight = 0; + // 赋值次序号和区间值累加的数组值,从小到大排列 + // 例如,对于权重分别为20,40, 60的三个服务,将形成[0, 20),[20, 60),[60, 120]三个区间 + for (int i = 0; i < weights.length; i++) { + if (weights[i] <= 0) { + continue; + } + + totalWeight += weights[i]; + weightHolder[i][0] = i; + weightHolder[i][1] = totalWeight; + } + + // 获取介于0(含)和n(不含)伪随机,均匀分布的int值 + int hitWeight = ThreadLocalRandom.current().nextInt(totalWeight) + 1; // [1, totalWeight) + for (int i = 0; i < weightHolder.length; i++) { + if (hitWeight <= weightHolder[i][1]) { + return weightHolder[i][0]; + } + } + + return weightHolder[0][0]; + } +} \ No newline at end of file diff --git a/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/ArrayWeightRandomLoadBalanceTest.java b/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/ArrayWeightRandomLoadBalanceTest.java index 5b4f2c8f18..0dc75f2591 100644 --- a/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/ArrayWeightRandomLoadBalanceTest.java +++ b/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/ArrayWeightRandomLoadBalanceTest.java @@ -14,10 +14,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ThreadLocalRandom; import org.apache.commons.collections4.CollectionUtils; +import com.nepxion.discovery.plugin.framework.loadbalance.weight.ArrayWeightRandom; + public class ArrayWeightRandomLoadBalanceTest { public static void main(String[] args) { test(1000000); @@ -51,7 +52,7 @@ public static void test(int totalCount) { int v4Count = 0; int v5Count = 0; for (int i = 0; i < totalCount; i++) { - String server = choose(serverList, weightMap); + String server = random(serverList, weightMap); if (server.startsWith("1.0")) { v1Count++; } @@ -81,7 +82,9 @@ public static void test(int totalCount) { System.out.println("------------------------------"); } - public static String choose(List serverList, Map weightMap) { + private static ArrayWeightRandom arrayWeightRandom = new ArrayWeightRandom(); + + public static String random(List serverList, Map weightMap) { if (CollectionUtils.isEmpty(serverList)) { return null; } @@ -92,36 +95,8 @@ public static String choose(List serverList, Map weight weights[i] = weightMap.get(server); } - int index = getIndex(weights); + int index = arrayWeightRandom.getIndex(weights); return serverList.get(index); } - - private static int getIndex(int[] weights) { - // 次序号/权重区间值 - int[][] weightHolder = new int[weights.length][2]; - // 总权重 - int totalWeight = 0; - // 赋值次序号和区间值累加的数组值,从小到大排列 - // 例如,对于权重分别为20,40, 60的三个服务,将形成[0, 20),[20, 60),[60, 120]三个区间 - for (int i = 0; i < weights.length; i++) { - if (weights[i] <= 0) { - continue; - } - - totalWeight += weights[i]; - weightHolder[i][0] = i; - weightHolder[i][1] = totalWeight; - } - - // 获取介于0(含)和n(不含)伪随机,均匀分布的int值 - int hitWeight = ThreadLocalRandom.current().nextInt(totalWeight) + 1; // [1, totalWeight) - for (int i = 0; i < weightHolder.length; i++) { - if (hitWeight <= weightHolder[i][1]) { - return weightHolder[i][0]; - } - } - - return weightHolder[0][0]; - } } \ No newline at end of file diff --git a/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/MapWeightRandomLoadBalanceTest.java b/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/MapWeightRandomLoadBalanceTest.java index 63496abe03..30392493b3 100644 --- a/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/MapWeightRandomLoadBalanceTest.java +++ b/discovery-plugin-framework/src/test/java/com/nepxion/discovery/plugin/framework/loadbalance/MapWeightRandomLoadBalanceTest.java @@ -12,14 +12,11 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; -import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; -import com.nepxion.discovery.common.exception.DiscoveryException; +import com.nepxion.discovery.plugin.framework.loadbalance.weight.MapWeightRandom; public class MapWeightRandomLoadBalanceTest { public static void main(String[] args) { @@ -77,31 +74,4 @@ public static void test(int totalCount) { System.out.println("耗时时间:" + (System.currentTimeMillis() - t)); System.out.println("------------------------------"); } - - public static class MapWeightRandom { - private TreeMap weightMap = new TreeMap(); - - public MapWeightRandom(List> pairlist) { - for (Pair pair : pairlist) { - double value = pair.getValue().doubleValue(); - if (value <= 0) { - continue; - } - - double lastWeight = weightMap.size() == 0 ? 0 : weightMap.lastKey().doubleValue(); - weightMap.put(value + lastWeight, pair.getKey()); - } - } - - public K random() { - if (MapUtils.isEmpty(weightMap)) { - throw new DiscoveryException("Weight values are all <= 0 or invalid format"); - } - - double randomWeight = weightMap.lastKey() * Math.random(); - SortedMap tailMap = weightMap.tailMap(randomWeight, false); - - return weightMap.get(tailMap.firstKey()); - } - } } \ No newline at end of file