路由规则
路由功能,就是 消费者 -> 提供者 即是根据配置的路由规则,找到提供者, 比如,读写分离 路由规则: 读路由: 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-路由规则 路由名称: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:
https://github.com/nytta
可以给个star,^0^.