路由规则
功能配置
路由功能,就是 消费者 -> 提供者
即是根据配置的路由规则,找到提供者,
比如,读写分离 路由规则:
读路由:
method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
这条规则会判断读方法,会调用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
这条规则会判断读方法,会调用172.22.3.97,172.22.3.98这几个提供者的服务
除读写分离路由规则,还有其他规则:http://dubbo.io/User+Guide-zh.htm#UserGuide-zh-%E8%B7%AF%E7%94%B1%E8%A7%84%E5%88%99
路由名称:name
服务名:service(一个路由规则只能对应一个服务)
优先级别:priority(优级越高排序越前)
route://0.0.0.0/lam.dubbo.privider.LoginService?category=routers&router=condition&runtime=false&enabled=true&priority=1&force=false&dynamic=false&name=LoginServiceRouter&rule=URL.encode(method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96)
下面是路由功能的实现:
private List<Invoker<T>> route(List<Invoker<T>> invokers, String method) {
Invocation invocation = new RpcInvocation(method, new Class<?>[0], new Object[0]);
List<Router> routers = getRouters();
if (routers != null) {
for (Router router : routers) {
if (router.getUrl() != null && ! router.getUrl().getParameter(Constants.RUNTIME_KEY, true)) {
invokers = router.route(invokers, getConsumerUrl(), invocation);//4处
}
}
}
return invokers;
}
从上面4处的invocation参数,看出是对方法一个一个来进行路由映射方法的提供者列表的,route实现,看下面源码:
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
if (invokers == null || invokers.size() == 0) {
return invokers;
}
try {
if (! matchWhen(url)) { //5处
return invokers;
}
List<Invoker<T>> result = new ArrayList<Invoker<T>>();
if (thenCondition == null) {
logger.warn("The current consumer in the service blacklist. consumer: " + NetUtils.getLocalHost() + ", service: " + url.getServiceKey());
return result;
}
for (Invoker<T> invoker : invokers) {
if (matchThen(invoker.getUrl(), url)) { //6处
result.add(invoker);
}
}
if (result.size() > 0) {
return result;
} else if (force) {
logger.warn("The route result is empty and force execute. consumer: " + NetUtils.getLocalHost() + ", service: " + url.getServiceKey() + ", router: " + url.getParameterAndDecoded(Constants.RULE_KEY));
return result;
}
} catch (Throwable t) {
logger.error("Failed to execute condition router rule: " + getUrl() + ", invokers: " + invokers + ", cause: " + t.getMessage(), t);
}
return invokers;
}
其中
代码的5处,判断消费者是否匹配路由规则的左边
比如,路由规则method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96,
规则左边,即判断消费者调用的方法是读方法
代码的6处,判断提供者是否匹配路由规则的右边
就像上面这条路由规则,即判断提供者是否这几个host的服务,否则不会被映射到方法的提供列表。
自己写了个RPC:
可以给个star,^0^.