06 dubbo源码学习_服务路由

1. 路由的作用

服务路由的作用就是可以限制消费者可以调用哪些服务提供者;

路由的规则:

[服务消费者匹配条件] => [服务提供者匹配条件]
如果消费者条件为空,则表示对所有消费方应用; => host != 10.20.153.11
如果服务提供者条件为空,表示禁止访问; host = 10.20.153.10 =>
=号,表示匹配,比如:host = 10.20.153.10
!=号,表示不匹配,比如:host != 10.20.153.10
参数值,号分隔多个值,比如:host != 10.20.153.10,10.20.153.11
号结尾表示通配符:host != 10.20.
服务调用信息,如:method, argument 等,暂不支持参数路由
URL 本身的字段,如:protocol, host, port 等
以及 URL 上的所有参数,如:application, organization 等

示例:

  1. => host != 172.22.3.91 所有消费方都不访问该地址;
  2. method = find*,list*,get*,is* => host = 172.22.3.94,172.22.3.95,172.22.3.96
    方法=find*,list*,get*,is*开头的都访问host=172.22.3.94,172.22.3.95,172.22.3.96
  3. method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98

2. 路由源码

它的源码入口从com.alibaba.dubbo.registry.integration.RegistryDirectory#route服务目录这里开始,

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'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);
            }
        }
    }
    return invokers;
}

从这里也可以看出,dubbo的路由是可以方法级别配置的;
com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouter#route

@Override
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation)
        throws RpcException {
    if (invokers == null || invokers.isEmpty()) {
        return invokers;
    }
    try {
        // 先对服务消费者条件进行匹配,如果匹配失败,表明服务消费者 url 不符合匹配规则,
        // 无需进行后续匹配,直接返回 Invoker 列表即可。比如下面的规则:
        //     host = 10.20.153.10 => host = 10.0.0.10
        // 这条路由规则希望 IP 为 10.20.153.10 的服务消费者调用 IP 为 10.0.0.10 机器上的服务。
        // 当消费者 ip 为 10.20.153.11 时,matchWhen 返回 false,表明当前这条路由规则不适用于
        // 当前的服务消费者,此时无需再进行后续匹配,直接返回即可。
        if (!matchWhen(url, invocation)) {
            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) {
            // 这里可以简单的把 Invoker 理解为服务提供者,现在使用服务提供者匹配规则对 
            // 若匹配成功,表明当前 Invoker 符合服务提供者匹配规则。
            if (matchThen(invoker.getUrl(), url)) {
                result.add(invoker);
            }
        }
        if (!result.isEmpty()) {
            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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值