The routing rules 1 determine the target server of one service call. It has two kinds of routing rules: conditional routing rules and script routing rules. It also support extension2.
Writing routing rules to the registry is usually done by the monitoring center or the console page.
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("route://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" + URL.encode("host = 10.20.153.10 => host = 10.20.153.11")));
其中:
route://
It indicates the type of routing rules, supports routing rules and script routing rules, and can be extended. Required。0.0.0.0
It indicates that all IP addresses are valid. If you want to take effect for only one IP address, fill in the IP address. Required。com.foo.BarService
It indicates that the specified service is effective. Required。group=foo
It indicates that the specified service in specified group is effective. When absent, the specified service which dosen’t configure group is effective.version=1.0
It indicates that the specified service in specified version is effective. When absent, the specified service which dosen’t configure version is effective.category=routers
It indicates that the data is a dynamic configuration type. Required。dynamic=false
It indicates that it is persistent data. When the registrant exits, the data is still stored in the registry. Required。enabled=true
It indicates whether this routing rules is effective. Option, and default effective.force=false
It indicates whether it is forced to be executed when the routing result is null. If it is not enforced, the route will be automatically invalidated. Option, and default false
.runtime=false
It indicates whether to execute routing rules at every call. If not, the result is only pre-executed and cached when the provider’s address list changes. It will get routing result from cache when the service is invoked. If you use parameter routing, you must to configure it as true
. Be careful that the configuration will affect the performance. Option, and default false
.priority=1
The priority of the routing rules. it is used for sorting, the greater the priority, the more front execution. Option, and default 0
。rule=URL.encode("host = 10.20.153.10 => host = 10.20.153.11")
It indicates the content of routing rule,Required。Routing rules based on conditional expressions, such as:host = 10.20.153.10 => host = 10.20.153.11
=>
is matched condition for consumer. All parameters compare with URL of consumers. When the consumer meet the condition, it will continue to execute the behind filter rules for consumer.=>
aims to filter the provider address list. All the parameters are compared against the provider’s URL, and consumer get only the filtered address list at finally.=> host != 10.20.153.11
host = 10.20.153.10 =>
Parameter Support:
Condition Support:
=
indicates match. such as: host = 10.20.153.10
!=
indicates “does not match”. such as: host != 10.20.153.10
.Value Support:
,
. Such as:host != 10.20.153.10,10.20.153.11
*
to indicate wildcard. Such as: host != 10.20.*
$
to indicate reference to consumer parameters. Such as: host = $host
Exclude pre-release machine:
=> host != 172.22.3.91
Whitelist 3:
register.ip != 10.20.153.10,10.20.153.11 =>
Blacklist:
register.ip = 10.20.153.10,10.20.153.11 =>
Service boarding application only expose part of the machine to prevent the entire cluster hanging up:
=> host = 172.22.3.1*,172.22.3.2*
Additional machines for important applications:
application != kylin => host != 172.22.3.95,172.22.3.96
Read and write separation:
method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98
Separation of Front and Background Application:
application = bops => host = 172.22.3.91,172.22.3.92,172.22.3.93
application != bops => host = 172.22.3.94,172.22.3.95,172.22.3.96
Isolate different network segments:
host != 172.22.3.* => host != 172.22.3.*
Providers and consumers deployed in the same cluster, the machine only visit the local service:
=> host = $host
Script routing rules 4 support all scripts of JDK script engine. such as: javascript, jruby, groovy, etc. Configure the script type by type=javascript
, the default is javascript.
"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule=" + URL.encode("(function route(invokers) { ... } (invokers))")
Routing rules that base on script engine is as follow:
(function route(invokers) {
var result = new java.util.ArrayList(invokers.size());
for (i = 0; i < invokers.size(); i ++) {
if ("10.20.153.10".equals(invokers.get(i).getUrl().getHost())) {
result.add(invokers.get(i));
}
}
return result;
} (invokers)); // Indicates that the method is executed immediately
Tag routing rules 5 , when the application configures the TagRouter
, a tagged dubbo invocation can intelligently route to the service provider which has the corresponding tag.
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("provider-book");
applicationConfig.setQosEnable(false);
// instruct tag router
Map<String,String> parameters = new HashMap<>();
parameters.put(Constants.ROUTER_KEY, "tag");
applicationConfig.setParameters(parameters);
return applicationConfig;
}
@Bean
public ProviderConfig providerConfig(){
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTag("red");
return providerConfig;
}
The application which configures no tag will be considered as the default application, and these default apps will be treated as downgrades when the invocation fails to match the provider.
RpcContext.getContext().setAttachment(Constants.TAG_KEY,"red");
The scope of the dubbo.tag
is for each invocation, using the attachment to pass the request tag. Note that the value stored in the attachment will be passed continuously in a complete remote invocation, thanks to this feature, we only need to set the tag at the beginning of a invocation.
Currently, only hardcoding is supported to set dubboTag. Note that RpcContext is thread-bound, elegantly using the TagRouter feature, it is recommended to set the request tag via a servlet filter (in the web environment) or a custom dubbo SPI filter.
dubbo.tag=red
will firstlt choose the provider which configures as tag=red
. If there is no service corresponding to the request tag in the cluster, it will downgrade to tag=null
provider, seen as default provider。
when dubbo.tag=null
, only tag=null
provider will be matched. Even if there are services available in the cluster, the tags do not match, they cannot be called. This is different from rule 1. Tagged invocation can be downgraded to untagged services, but invocations that do not carry tags/carry other types of tags can never be accessed other tag services.