diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java
index 2e3ab143a4d..090f2862e67 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java
@@ -22,6 +22,7 @@
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
@@ -94,17 +95,18 @@ public void destroy() {
/**
* Select a invoker using loadbalance policy.
- * a)Firstly, select an invoker using loadbalance. If this invoker is in previously selected list, or,
+ * a) Firstly, select an invoker using loadbalance. If this invoker is in previously selected list, or,
* if this invoker is unavailable, then continue step b (reselect), otherwise return the first selected invoker
- * b)Reslection, the validation rule for reselection: selected > available. This rule guarantees that
+ *
+ * b) Reslection, the validation rule for reselection: selected > available. This rule guarantees that
* the selected invoker has the minimum chance to be one in the previously selected list, and also
* guarantees this invoker is available.
*
* @param loadbalance load balance policy
- * @param invocation
- * @param invokers invoker candidates
- * @param selected exclude selected invokers or not
- * @return
+ * @param invocation invocation
+ * @param invokers invoker candidates
+ * @param selected exclude selected invokers or not
+ * @return the invoker which will final to do invoke.
* @throws RpcException
*/
protected Invoker select(LoadBalance loadbalance, Invocation invocation, List> invokers, List> selected) throws RpcException {
@@ -138,9 +140,6 @@ private Invoker doSelect(LoadBalance loadbalance, Invocation invocation, List
return null;
if (invokers.size() == 1)
return invokers.get(0);
- if (loadbalance == null) {
- loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
- }
Invoker invoker = loadbalance.select(invokers, getUrl(), invocation);
//If the `invoker` is in the `selected` or invoker is unavailable && availablecheck is true, reselect.
@@ -226,7 +225,6 @@ private Invoker reselect(LoadBalance loadbalance, Invocation invocation,
@Override
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
- LoadBalance loadbalance = null;
// binding attachments into invocation.
Map contextAttachments = RpcContext.getContext().getAttachments();
@@ -235,10 +233,7 @@ public Result invoke(final Invocation invocation) throws RpcException {
}
List> invokers = list(invocation);
- if (invokers != null && !invokers.isEmpty()) {
- loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
- .getMethodParameter(RpcUtils.getMethodName(invocation), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
- }
+ LoadBalance loadbalance = initLoadBalance(invokers, invocation);
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
@@ -276,4 +271,24 @@ protected List> list(Invocation invocation) throws RpcException {
List> invokers = directory.list(invocation);
return invokers;
}
+
+ /**
+ * Init LoadBalance.
+ *
+ * if invokers is not empty, init from the first invoke's url and invocation
+ * if invokes is empty, init a default LoadBalance(RandomLoadBalance)
+ *
+ *
+ * @param invokers invokers
+ * @param invocation invocation
+ * @return LoadBalance instance. if not need init, return null.
+ */
+ protected LoadBalance initLoadBalance(List> invokers, Invocation invocation) {
+ if (CollectionUtils.isNotEmpty(invokers)) {
+ return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
+ .getMethodParameter(RpcUtils.getMethodName(invocation), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
+ } else {
+ return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
+ }
+ }
}
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
index c249131227e..247a719ad84 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvokerTest.java
@@ -51,7 +51,6 @@
/**
* AbstractClusterInvokerTest
- *
*/
@SuppressWarnings("rawtypes")
public class AbstractClusterInvokerTest {
@@ -161,14 +160,16 @@ protected Result doInvoke(Invocation invocation, List invokers, LoadBalance load
@Test
public void testSelect_Invokersize0() throws Exception {
+ LoadBalance l = cluster.initLoadBalance(invokers, invocation);
+ Assert.assertNotNull("cluster.initLoadBalance returns null!", l);
{
- Invoker invoker = cluster.select(null, null, null, null);
+ Invoker invoker = cluster.select(l, null, null, null);
Assert.assertEquals(null, invoker);
}
{
invokers.clear();
selectedInvokers.clear();
- Invoker invoker = cluster.select(null, null, invokers, null);
+ Invoker invoker = cluster.select(l, null, invokers, null);
Assert.assertEquals(null, invoker);
}
}
@@ -177,7 +178,9 @@ public void testSelect_Invokersize0() throws Exception {
public void testSelect_Invokersize1() throws Exception {
invokers.clear();
invokers.add(invoker1);
- Invoker invoker = cluster.select(null, null, invokers, null);
+ LoadBalance l = cluster.initLoadBalance(invokers, invocation);
+ Assert.assertNotNull("cluster.initLoadBalance returns null!", l);
+ Invoker invoker = cluster.select(l, null, invokers, null);
Assert.assertEquals(invoker1, invoker);
}
@@ -186,16 +189,18 @@ public void testSelect_Invokersize2AndselectNotNull() throws Exception {
invokers.clear();
invokers.add(invoker2);
invokers.add(invoker4);
+ LoadBalance l = cluster.initLoadBalance(invokers, invocation);
+ Assert.assertNotNull("cluster.initLoadBalance returns null!", l);
{
selectedInvokers.clear();
selectedInvokers.add(invoker4);
- Invoker invoker = cluster.select(null, invocation, invokers, selectedInvokers);
+ Invoker invoker = cluster.select(l, invocation, invokers, selectedInvokers);
Assert.assertEquals(invoker2, invoker);
}
{
selectedInvokers.clear();
selectedInvokers.add(invoker2);
- Invoker invoker = cluster.select(null, invocation, invokers, selectedInvokers);
+ Invoker invoker = cluster.select(l, invocation, invokers, selectedInvokers);
Assert.assertEquals(invoker4, invoker);
}
}