Skip to content

Commit

Permalink
增加自定义全链路随机权重
Browse files Browse the repository at this point in the history
  • Loading branch information
HaojunRen committed Dec 29, 2019
1 parent 2dbdcfb commit 09b55fb
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
*/

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.commons.collections4.CollectionUtils;

import com.nepxion.discovery.plugin.framework.loadbalance.WeightRandomLoadBalance;
import com.netflix.loadbalancer.Server;

public abstract class AbstractArrayWeightRandomLoadBalance<T> implements WeightRandomLoadBalance<T> {
private ArrayWeightRandom arrayWeightRandom = new ArrayWeightRandom();

@Override
public Server choose(List<Server> serverList, T t) {
if (CollectionUtils.isEmpty(serverList)) {
Expand All @@ -30,36 +31,8 @@ public Server choose(List<Server> 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];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.nepxion.discovery.plugin.framework.loadbalance.weight;

/**
* <p>Title: Nepxion Discovery</p>
* <p>Description: Nepxion Discovery</p>
* <p>Copyright: Copyright (c) 2017-2050</p>
* <p>Company: Nepxion</p>
* @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];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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++;
}
Expand Down Expand Up @@ -81,7 +82,9 @@ public static void test(int totalCount) {
System.out.println("------------------------------");
}

public static String choose(List<String> serverList, Map<String, Integer> weightMap) {
private static ArrayWeightRandom arrayWeightRandom = new ArrayWeightRandom();

public static String random(List<String> serverList, Map<String, Integer> weightMap) {
if (CollectionUtils.isEmpty(serverList)) {
return null;
}
Expand All @@ -92,36 +95,8 @@ public static String choose(List<String> serverList, Map<String, Integer> 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];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -77,31 +74,4 @@ public static void test(int totalCount) {
System.out.println("耗时时间:" + (System.currentTimeMillis() - t));
System.out.println("------------------------------");
}

public static class MapWeightRandom<K, V extends Number> {
private TreeMap<Double, K> weightMap = new TreeMap<Double, K>();

public MapWeightRandom(List<Pair<K, V>> pairlist) {
for (Pair<K, V> 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<Double, K> tailMap = weightMap.tailMap(randomWeight, false);

return weightMap.get(tailMap.firstKey());
}
}
}

0 comments on commit 09b55fb

Please sign in to comment.