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); } }