diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java index a5eea1c9bf67..aa6d7a2a8d21 100644 --- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java @@ -51,4 +51,11 @@ public interface Router extends Comparable { */ List> route(List> invokers, URL url, Invocation invocation) throws RpcException; + /** + * router priority + * + * @return + */ + int getPriority(); + } \ No newline at end of file diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/AbstractRouter.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/AbstractRouter.java new file mode 100644 index 000000000000..5cd2453fd4a5 --- /dev/null +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/AbstractRouter.java @@ -0,0 +1,25 @@ +package com.alibaba.dubbo.rpc.cluster.router; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.rpc.cluster.Router; + +public abstract class AbstractRouter implements Router { + + protected int priority; + protected URL url; + + @Override + public URL getUrl() { + return url; + } + + @Override + public int getPriority() { + return priority; + } + + @Override + public int compareTo(Router o) { + return (this.getPriority() >= o.getPriority()) ? 1 : -1; + } +} diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/MockInvokersSelector.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/MockInvokersSelector.java index d406f78da4f1..487508e682e0 100644 --- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/MockInvokersSelector.java +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/MockInvokersSelector.java @@ -31,7 +31,7 @@ * If a request is configured to use mock, then this router guarantees that only the invokers with protocol MOCK appear in final the invoker list, all other invokers will be excluded. * */ -public class MockInvokersSelector implements Router { +public class MockInvokersSelector extends AbstractRouter { @Override public List> route(final List> invokers, @@ -87,11 +87,12 @@ private boolean hasMockProviders(final List> invokers) { return hasMockProvider; } - @Override - public URL getUrl() { - return null; - } - + /** + * Always stay on the top of the list + * + * @param o + * @return + */ @Override public int compareTo(Router o) { return 1; diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/condition/ConditionRouter.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/condition/ConditionRouter.java index 05f1d7136dc0..c8125d351e6b 100644 --- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/condition/ConditionRouter.java +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/condition/ConditionRouter.java @@ -26,7 +26,7 @@ import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.RpcException; -import com.alibaba.dubbo.rpc.cluster.Router; +import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter; import java.text.ParseException; import java.util.ArrayList; @@ -42,12 +42,10 @@ * ConditionRouter * */ -public class ConditionRouter implements Router, Comparable { +public class ConditionRouter extends AbstractRouter { private static final Logger logger = LoggerFactory.getLogger(ConditionRouter.class); private static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)"); - private final URL url; - private final int priority; private final boolean force; private final Map whenCondition; private final Map thenCondition; @@ -174,20 +172,6 @@ public List> route(List> invokers, URL url, Invocation return invokers; } - @Override - public URL getUrl() { - return url; - } - - @Override - public int compareTo(Router o) { - if (o == null || o.getClass() != ConditionRouter.class) { - return 1; - } - ConditionRouter c = (ConditionRouter) o; - return this.priority == c.priority ? url.toFullString().compareTo(c.url.toFullString()) : (this.priority > c.priority ? 1 : -1); - } - boolean matchWhen(URL url, Invocation invocation) { return whenCondition == null || whenCondition.isEmpty() || matchCondition(whenCondition, url, null, invocation); } diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java index 74938c6439ef..4c2e7c426bb1 100644 --- a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/script/ScriptRouter.java @@ -24,7 +24,7 @@ import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.RpcContext; import com.alibaba.dubbo.rpc.RpcException; -import com.alibaba.dubbo.rpc.cluster.Router; +import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter; import javax.script.Bindings; import javax.script.Compilable; @@ -42,7 +42,7 @@ * ScriptRouter * */ -public class ScriptRouter implements Router { +public class ScriptRouter extends AbstractRouter { private static final Logger logger = LoggerFactory.getLogger(ScriptRouter.class); @@ -50,12 +50,8 @@ public class ScriptRouter implements Router { private final ScriptEngine engine; - private final int priority; - private final String rule; - private final URL url; - public ScriptRouter(URL url) { this.url = url; String type = url.getParameter(Constants.TYPE_KEY); @@ -79,11 +75,6 @@ public ScriptRouter(URL url) { this.rule = rule; } - @Override - public URL getUrl() { - return url; - } - @Override @SuppressWarnings("unchecked") public List> route(List> invokers, URL url, Invocation invocation) throws RpcException { @@ -114,13 +105,4 @@ public List> route(List> invokers, URL url, Invocation } } - @Override - public int compareTo(Router o) { - if (o == null || o.getClass() != ScriptRouter.class) { - return 1; - } - ScriptRouter c = (ScriptRouter) o; - return this.priority == c.priority ? rule.compareTo(c.rule) : (this.priority > c.priority ? 1 : -1); - } - } diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouter.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouter.java new file mode 100644 index 000000000000..dad70d333126 --- /dev/null +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouter.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.rpc.cluster.router.tag; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.RpcContext; +import com.alibaba.dubbo.rpc.RpcException; +import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter; + +import java.util.ArrayList; +import java.util.List; + +/** + * TagRouter + */ +public class TagRouter extends AbstractRouter { + + private static final Logger logger = LoggerFactory.getLogger(TagRouter.class); + private static final int DEFAULT_PRIORITY = 100; + private static final URL ROUTER_URL = new URL("tag", Constants.ANYHOST_VALUE, 0, Constants.ANY_VALUE).addParameters(Constants.RUNTIME_KEY, "true"); + + public TagRouter(URL url) { + this.url = url; + this.priority = url.getParameter(Constants.PRIORITY_KEY, DEFAULT_PRIORITY); + } + + public TagRouter() { + this.url = ROUTER_URL; + this.priority = url.getParameter(Constants.PRIORITY_KEY, DEFAULT_PRIORITY); + } + + @Override + public URL getUrl() { + return url; + } + + @Override + public List> route(List> invokers, URL url, Invocation invocation) throws RpcException { + // filter + List> result = new ArrayList>(); + try { + // Dynamic param + String tag = RpcContext.getContext().getAttachment(Constants.REQUEST_TAG_KEY); + // Tag request + if (!StringUtils.isEmpty(tag)) { + // Select tag invokers first + for (Invoker invoker : invokers) { + if (tag.equals(invoker.getUrl().getParameter(Constants.TAG_KEY))) { + result.add(invoker); + } + } + } + // If Constants.REQUEST_TAG_KEY unspecified or no invoker be selected, downgrade to normal invokers + if (result.isEmpty()) { + for (Invoker invoker : invokers) { + if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) { + result.add(invoker); + } + } + } + return result; + } catch (Exception e) { + logger.error("Route by tag error,return all invokers.", e); + } + // Downgrade to all invokers + return invokers; + } + +} diff --git a/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterFactory.java b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterFactory.java new file mode 100644 index 000000000000..08373afb99a3 --- /dev/null +++ b/dubbo-cluster/src/main/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterFactory.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.rpc.cluster.router.tag; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.rpc.cluster.Router; +import com.alibaba.dubbo.rpc.cluster.RouterFactory; + +public class TagRouterFactory implements RouterFactory { + + public static final String NAME = "tag"; + + @Override + public Router getRouter(URL url) { + return new TagRouter(url); + } +} diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory index 239c6f0b625a..446cef30fee3 100644 --- a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.cluster.RouterFactory @@ -1,3 +1,4 @@ file=com.alibaba.dubbo.rpc.cluster.router.file.FileRouterFactory script=com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory -condition=com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouterFactory \ No newline at end of file +condition=com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouterFactory +tag=com.alibaba.dubbo.rpc.cluster.router.tag.TagRouterFactory \ No newline at end of file diff --git a/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterTest.java b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterTest.java new file mode 100644 index 000000000000..1cb053c3e48c --- /dev/null +++ b/dubbo-cluster/src/test/java/com/alibaba/dubbo/rpc/cluster/router/tag/TagRouterTest.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.rpc.cluster.router.tag; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.extension.ExtensionLoader; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.RpcContext; +import com.alibaba.dubbo.rpc.RpcInvocation; +import com.alibaba.dubbo.rpc.cluster.Router; +import com.alibaba.dubbo.rpc.cluster.RouterFactory; +import com.alibaba.dubbo.rpc.cluster.router.MockInvoker; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TagRouterTest { + + private URL tagUrl = new URL("tag" + , Constants.ANYHOST_VALUE, 0 + , Constants.ANY_VALUE) + .addParameters( + Constants.RUNTIME_KEY, "true" + ); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @Test + public void testRoute_matchTag() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "red"); + + List> invokers = new ArrayList>(); + Invoker redInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(redInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(defaultInvoker)); + } + + @Test + public void testRoute_matchDefault() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, ""); + + List> invokers = new ArrayList>(); + Invoker redInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(defaultInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(redInvoker)); + } + + @Test + public void testRoute_requestWithTag_shouldDowngrade() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "black"); + + List> invokers = new ArrayList>(); + Invoker redInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(defaultInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(redInvoker)); + } + + @Test + public void testRoute_requestWithoutTag_shouldNotDowngrade() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, ""); + + List> invokers = new ArrayList>(); + Invoker redInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertEquals(0, filteredInvokers.size()); + } + + @Test + public void testRoute_createBySpi() { + URL zkProvider = URL.valueOf("zookeeper://10.20.3.1:20880/com.foo.BarService?router=tag"); + String parameter = zkProvider.getParameter(Constants.ROUTER_KEY); + RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(parameter); + Router tagRouter = routerFactory.getRouter(zkProvider); + Assert.assertTrue(tagRouter instanceof TagRouter); + } + +} diff --git a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java index 02d70ea809bd..c84e74542312 100644 --- a/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java +++ b/dubbo-common/src/main/java/com/alibaba/dubbo/common/Constants.java @@ -637,6 +637,11 @@ public class Constants { public static final String SERVICE_IMPL_CLASS = "service.classimpl"; + public static final String TAG_KEY = "tag"; + + public static final String REQUEST_TAG_KEY = "request.tag"; + + /* * private Constants(){ } */ diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractServiceConfig.java index 68903988da4c..2e75f36a975f 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractServiceConfig.java @@ -73,6 +73,9 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig { // serialization private String serialization; + // provider tag + protected String tag; + public String getVersion() { return version; } @@ -240,4 +243,12 @@ public void setSerialization(String serialization) { this.serialization = serialization; } + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + } diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java index 4d682273171f..0f094f98076e 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java +++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java @@ -120,4 +120,6 @@ String[] registry() default {}; + String tag() default ""; + } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java index 722c6d052138..84a01f8ea64e 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java @@ -185,6 +185,9 @@ public Object postProcessAfterInitialization(Object bean, String beanName) } serviceConfig.setProtocols(protocolConfigs); } + if (service.tag().length() > 0) { + serviceConfig.setTag(service.tag()); + } try { serviceConfig.afterPropertiesSet(); } catch (RuntimeException e) { diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd index c48e2c3deabd..ffa74ca3c5d6 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd @@ -312,6 +312,11 @@ + + + + + diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 40a7ac6c723e..19361d69199d 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -312,6 +312,11 @@ + + + + + diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/integration/RegistryDirectory.java index 4bd0908a1edb..68ecc0e9efb4 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/integration/RegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/com/alibaba/dubbo/registry/integration/RegistryDirectory.java @@ -445,7 +445,8 @@ private List> route(List> invokers, String method) { List routers = getRouters(); if (routers != null) { for (Router router : routers) { - if (router.getUrl() != null) { + // If router's url not null and is not route by runtime,we filter invokers here + if (router.getUrl() != null && !router.getUrl().getParameter(Constants.RUNTIME_KEY, false)) { invokers = router.route(invokers, getConsumerUrl(), invocation); } }