carryxyh closed pull request #2584: Optimize LeastActiveLoadBalance and add
weight test case.
URL: https://github.com/apache/incubator-dubbo/pull/2584
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LeastActiveLoadBalance.java
b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LeastActiveLoadBalance.java
index aa6ec12c23..a3847f4b76 100644
---
a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LeastActiveLoadBalance.java
+++
b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LeastActiveLoadBalance.java
@@ -16,7 +16,6 @@
*/
package com.alibaba.dubbo.rpc.cluster.loadbalance;
-import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
@@ -41,26 +40,26 @@
int leastActive = -1; // The least active value of all invokers
int leastCount = 0; // The number of invokers having the same least
active value (leastActive)
int[] leastIndexs = new int[length]; // The index of invokers having
the same least active value (leastActive)
- int totalWeight = 0; // The sum of weights
+ int totalWeight = 0; // The sum of with warmup weights
int firstWeight = 0; // Initial value, used for comparision
boolean sameWeight = true; // Every invoker has the same weight value?
for (int i = 0; i < length; i++) {
Invoker<T> invoker = invokers.get(i);
int active = RpcStatus.getStatus(invoker.getUrl(),
invocation.getMethodName()).getActive(); // Active number
- int weight =
invoker.getUrl().getMethodParameter(invocation.getMethodName(),
Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT); // Weight
+ int afterWarmup = getWeight(invoker, invocation); // Weight
if (leastActive == -1 || active < leastActive) { // Restart, when
find a invoker having smaller least active value.
leastActive = active; // Record the current least active value
leastCount = 1; // Reset leastCount, count again based on
current leastCount
leastIndexs[0] = i; // Reset
- totalWeight = weight; // Reset
- firstWeight = weight; // Record the weight the first invoker
+ totalWeight = afterWarmup; // Reset
+ firstWeight = afterWarmup; // Record the weight the first
invoker
sameWeight = true; // Reset, every invoker has the same weight
value?
} else if (active == leastActive) { // If current invoker's active
value equals with leaseActive, then accumulating.
leastIndexs[leastCount++] = i; // Record index number of this
invoker
- totalWeight += weight; // Add this invoker's weight to
totalWeight.
+ totalWeight += afterWarmup; // Add this invoker's weight to
totalWeight.
// If every invoker has the same weight?
if (sameWeight && i > 0
- && weight != firstWeight) {
+ && afterWarmup != firstWeight) {
sameWeight = false;
}
}
@@ -72,7 +71,7 @@
}
if (!sameWeight && totalWeight > 0) {
// If (not every invoker has the same weight & at least one
invoker's weight>0), select randomly based on totalWeight.
- int offsetWeight = random.nextInt(totalWeight);
+ int offsetWeight = random.nextInt(totalWeight) + 1;
// Return a invoker based on the random value.
for (int i = 0; i < leastCount; i++) {
int leastIndex = leastIndexs[i];
diff --git
a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
index 442b1087da..bdede14a4f 100644
---
a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
+++
b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/loadbalance/LoadBalanceTest.java
@@ -21,9 +21,9 @@
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
+import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.RpcStatus;
import com.alibaba.dubbo.rpc.cluster.LoadBalance;
-
import junit.framework.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -40,7 +40,6 @@
/**
* RoundRobinLoadBalanceTest
- *
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class LoadBalanceTest {
@@ -52,6 +51,11 @@
Invoker<LoadBalanceTest> invoker4;
Invoker<LoadBalanceTest> invoker5;
+ RpcStatus weightTestRpcStatus1;
+ RpcStatus weightTestRpcStatus2;
+ RpcStatus weightTestRpcStatus3;
+ RpcInvocation weightTestInvocation;
+
/**
* @throws java.lang.Exception
*/
@@ -117,6 +121,81 @@ public void testRoundRobinLoadBalance_select() {
}
}
+ @Test
+ public void testSelectByWeightLeastActive() {
+ int sumInvoker1 = 0;
+ int sumInvoker2 = 0;
+ int loop = 10000;
+ LeastActiveLoadBalance lb = new LeastActiveLoadBalance();
+ for (int i = 0; i < loop; i++) {
+ Invoker selected = lb.select(weightInvokers, null,
weightTestInvocation);
+ if (selected.getUrl().getProtocol().equals("test1")) {
+ sumInvoker1++;
+ }
+ if (selected.getUrl().getProtocol().equals("test2")) {
+ sumInvoker2++;
+ }
+ // never select invoker3 because it's active is more than invoker1
and invoker2
+ Assert.assertTrue("select is not the least active one",
!selected.getUrl().getProtocol().equals("test3"));
+ }
+ // the sumInvoker1 : sumInvoker2 approximately equal to 1: 9
+ System.out.println(sumInvoker1);
+ System.out.println(sumInvoker2);
+ Assert.assertEquals("select failed!", sumInvoker1 + sumInvoker2, loop);
+ }
+
+ @Test
+ public void testSelectByWeightRandom() {
+ int sumInvoker1 = 0;
+ int sumInvoker2 = 0;
+ int sumInvoker3 = 0;
+ int loop = 10000;
+ RandomLoadBalance lb = new RandomLoadBalance();
+ for (int i = 0; i < loop; i++) {
+ Invoker selected = lb.select(weightInvokers, null,
weightTestInvocation);
+ if (selected.getUrl().getProtocol().equals("test1")) {
+ sumInvoker1++;
+ }
+ if (selected.getUrl().getProtocol().equals("test2")) {
+ sumInvoker2++;
+ }
+ if (selected.getUrl().getProtocol().equals("test3")) {
+ sumInvoker3++;
+ }
+ }
+ // 1 : 9 : 6
+ System.out.println(sumInvoker1);
+ System.out.println(sumInvoker2);
+ System.out.println(sumInvoker3);
+ Assert.assertEquals("select failed!", sumInvoker1 + sumInvoker2 +
sumInvoker3, loop);
+ }
+
+ @Test
+ public void testSelectByWeight() {
+ int sumInvoker1 = 0;
+ int sumInvoker2 = 0;
+ int sumInvoker3 = 0;
+ int loop = 10000;
+ RoundRobinLoadBalance lb = new RoundRobinLoadBalance();
+ for (int i = 0; i < loop; i++) {
+ Invoker selected = lb.select(weightInvokers, null,
weightTestInvocation);
+ if (selected.getUrl().getProtocol().equals("test1")) {
+ sumInvoker1++;
+ }
+ if (selected.getUrl().getProtocol().equals("test2")) {
+ sumInvoker2++;
+ }
+ if (selected.getUrl().getProtocol().equals("test3")) {
+ sumInvoker3++;
+ }
+ }
+ // 1 : 9 : 6
+ System.out.println(sumInvoker1);
+ System.out.println(sumInvoker2);
+ System.out.println(sumInvoker3);
+ Assert.assertEquals("select failed!", sumInvoker1 + sumInvoker2 +
sumInvoker3, loop);
+ }
+
@Test
public void testRandomLoadBalance_select() {
int runs = 1000;
@@ -125,7 +204,7 @@ public void testRandomLoadBalance_select() {
Long count = counter.get(minvoker).get();
// System.out.println(count);
Assert.assertTrue("abs diff shoud < avg",
- Math.abs(count - runs / (0f + invokers.size())) < runs / (0f +
invokers.size()));
+ Math.abs(count - runs / (0f + invokers.size())) < runs /
(0f + invokers.size()));
}
for (int i = 0; i < 5; i++) {
@@ -152,7 +231,7 @@ public void testLeastActiveLoadBalance_select() {
Long count = counter.get(minvoker).get();
// System.out.println(count);
Assert.assertTrue("abs diff shoud < avg",
- Math.abs(count - runs / (0f + invokers.size())) < runs / (0f +
invokers.size()));
+ Math.abs(count - runs / (0f + invokers.size())) < runs /
(0f + invokers.size()));
}
}
@@ -172,33 +251,74 @@ public void testLeastActiveLoadBalance_select() {
@Test
public void testLoadBalanceWarmup() {
Assert.assertEquals(1,
- AbstractLoadBalance.calculateWarmupWeight(0,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ AbstractLoadBalance.calculateWarmupWeight(0,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(1,
- AbstractLoadBalance.calculateWarmupWeight(13,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ AbstractLoadBalance.calculateWarmupWeight(13,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(1,
- AbstractLoadBalance.calculateWarmupWeight(6 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ AbstractLoadBalance.calculateWarmupWeight(6 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(2,
- AbstractLoadBalance.calculateWarmupWeight(12 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ AbstractLoadBalance.calculateWarmupWeight(12 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(10,
- AbstractLoadBalance.calculateWarmupWeight(60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ AbstractLoadBalance.calculateWarmupWeight(60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(50, AbstractLoadBalance
- .calculateWarmupWeight(5 * 60 * 1000, Constants.DEFAULT_WARMUP,
Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(5 * 60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(50, AbstractLoadBalance
- .calculateWarmupWeight(5 * 60 * 1000 + 23,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(5 * 60 * 1000 + 23,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(50, AbstractLoadBalance
- .calculateWarmupWeight(5 * 60 * 1000 + 5999,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(5 * 60 * 1000 + 5999,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(51, AbstractLoadBalance
- .calculateWarmupWeight(5 * 60 * 1000 + 6000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(5 * 60 * 1000 + 6000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(90, AbstractLoadBalance
- .calculateWarmupWeight(9 * 60 * 1000, Constants.DEFAULT_WARMUP,
Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(9 * 60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(98, AbstractLoadBalance
- .calculateWarmupWeight(10 * 60 * 1000 - 12 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(10 * 60 * 1000 - 12 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(99, AbstractLoadBalance
- .calculateWarmupWeight(10 * 60 * 1000 - 6 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(10 * 60 * 1000 - 6 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(100, AbstractLoadBalance
- .calculateWarmupWeight(10 * 60 * 1000, Constants.DEFAULT_WARMUP,
Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(10 * 60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
Assert.assertEquals(100, AbstractLoadBalance
- .calculateWarmupWeight(20 * 60 * 1000, Constants.DEFAULT_WARMUP,
Constants.DEFAULT_WEIGHT));
+ .calculateWarmupWeight(20 * 60 * 1000,
Constants.DEFAULT_WARMUP, Constants.DEFAULT_WEIGHT));
}
+ /*------------------------------------test invokers for
weight---------------------------------------*/
+
+ protected List<Invoker<LoadBalanceTest>> weightInvokers = new
ArrayList<Invoker<LoadBalanceTest>>();
+ protected Invoker<LoadBalanceTest> weightInvoker1;
+ protected Invoker<LoadBalanceTest> weightInvoker2;
+ protected Invoker<LoadBalanceTest> weightInvoker3;
+
+ @Before
+ public void before() throws Exception {
+ weightInvoker1 = mock(Invoker.class);
+ weightInvoker2 = mock(Invoker.class);
+ weightInvoker3 = mock(Invoker.class);
+ weightTestInvocation = new RpcInvocation();
+ weightTestInvocation.setMethodName("test");
+ URL url1 = URL.valueOf("test1://0:1/DemoService");
+ url1 = url1.addParameter(Constants.WEIGHT_KEY, 1);
+ url1 = url1.addParameter(weightTestInvocation.getMethodName() + "." +
Constants.WEIGHT_KEY, 1);
+ url1 = url1.addParameter("active", 0);
+ URL url2 = URL.valueOf("test2://0:9/DemoService");
+ url2 = url2.addParameter(Constants.WEIGHT_KEY, 9);
+ url2 = url2.addParameter(weightTestInvocation.getMethodName() + "." +
Constants.WEIGHT_KEY, 9);
+ url2 = url2.addParameter("active", 0);
+ URL url3 = URL.valueOf("test3://1:6/DemoService");
+ url3 = url3.addParameter(Constants.WEIGHT_KEY, 6);
+ url3 = url3.addParameter(weightTestInvocation.getMethodName() + "." +
Constants.WEIGHT_KEY, 6);
+ url3 = url3.addParameter("active", 1);
+ given(weightInvoker1.isAvailable()).willReturn(true);
+ given(weightInvoker1.getUrl()).willReturn(url1);
+ given(weightInvoker2.isAvailable()).willReturn(true);
+ given(weightInvoker2.getUrl()).willReturn(url2);
+ given(weightInvoker3.isAvailable()).willReturn(true);
+ given(weightInvoker3.getUrl()).willReturn(url3);
+ weightInvokers.add(weightInvoker1);
+ weightInvokers.add(weightInvoker2);
+ weightInvokers.add(weightInvoker3);
+ weightTestRpcStatus1 = RpcStatus.getStatus(weightInvoker1.getUrl(),
weightTestInvocation.getMethodName());
+ weightTestRpcStatus2 = RpcStatus.getStatus(weightInvoker2.getUrl(),
weightTestInvocation.getMethodName());
+ weightTestRpcStatus3 = RpcStatus.getStatus(weightInvoker3.getUrl(),
weightTestInvocation.getMethodName());
+ // weightTestRpcStatus3 active is 1
+ RpcStatus.beginCount(weightInvoker3.getUrl(),
weightTestInvocation.getMethodName());
+ }
}
\ No newline at end of file
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services