• Dubbo架构篇 - 服务路由


    前言

    服务目录在刷新Invoker列表的过程中,会通过Router进行服务路由,筛选出符合路由规则的服务提供者。

    服务路由包含一条路由规则,路由规则决定了服务消费者可以调用哪些服务提供者。

    Dubbo目前提供了三种服务路由实现 - 条件路由(ConditionRouter)、脚本路由(ScriptRouter)、标签路由(TagRouter)。


    条件路由的使用

    可以在服务治理控制台 Dubbo-Admin 写入路由规则

    应用粒度

    # app1的消费者只能消费所有端口为20880的服务实例
    # app2的消费者只能消费所有端口为20881的服务实例
    
    scope: application
    key: governance-conditionrouter-consumer
    enabled: true
    force: true
    runtine: true
    conditions:
    	- application=app1 => address=*:20880
    	- application=app2 => address=*:20881
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    服务粒度

    # DemoService的sayHello方法只能消费所有端口为20880的服务实例
    # DemoService的sayHi方法只能消费所有端口为20881的服务实例
    
    scope: service
    key: org.apache.dubbo.samples.goverance.api.DemoService
    enabled: true
    force: true
    runtime: true
    conditions:
    	- method=sayHello => address=*:20880
    	- method=sayHi => address=*:20881
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    • scope:表示路由规则的作用粒度,scope的取值会决定key的取值。必填。

      • application:应用粒度
      • service:服务粒度
    • key:明确规则体作用在哪个应用或者规则。必填

      • scope=application时,key取值为application名称。
      • scope=service时,key的取值为[{group}:]{service}[:{version}] 的组合。
    • conditions:定义具体的路由规则内容。必填

    • enabled:当前路由规则是否生效,缺省生效。

    • force:当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,缺省为 false。

    • runtime:是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。如果用了参数路由,必须设置为true,需要注意设置会影响调用的性能。缺省为false。

    • priority:路由规则的优先级,用于排序,优先级越大越靠前执行。缺省为0。

    Conditions规则体

    1、格式

    • => 之前的为消费者匹配条件,所有参数和消费者的URL进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。

    • => 之后的为提供者地址列表的过滤条件,所有参数和提供者的URL进行对比,消费者最终只拿到过滤后的地址列表。

    • 如果匹配条件为空,表示对所有消费者应用,比如:=> host != 10.20.153.11

    • 如果过滤条件为空,表示禁止访问,比如:host = 10.20.153.10 =>

    2、表达式

    参数支持

    • 服务调用信息,比如:method、argument 等,暂不支持参数路由
    • URL本身的字段,比如:protocol、host、port 等
    • URL上的所有参数,比如:application、organization 等

    条件支持

    • 等号 = 表示匹配,比如 host = 10.20.153.10
    • 不等号 != 表示不匹配,比如 host != 10.20.153.10

    值支持

    • 以逗号 , 分隔多个值,比如:host != 10.20.153.10,10.20.153.11

    • 以星号 * 结尾,表示通配,比如:host != 10.20.*

    • 以美元符 $ 开头,表示引用消费者参数,比如:host = $host

    3、示例

    排除预发布机

    => host != 172.22.3.91
    
    • 1

    白名单(一个服务只能有一个白名单规则,否则两条规则交叉,都被筛选掉了)

    register.ip != 10.20.153.10,10.20.153.11 =>
    
    • 1

    黑名单

    register.ip = 10.20.153.10,10.20.153.11 =>
    
    • 1

    提供者与消费者部署在同集群内,本机只访问本机的服务:

    => host = $host
    
    • 1

    隔离不同机房网段

    host != 172.22.3.* => host != 172.22.3.*
    
    • 1

    前后台分离

    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
    
    • 1
    • 2

    读写分离

    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
    
    • 1
    • 2

    为重要应用提供额外的机器

    application != kylin => host != 172.22.3.95,172.22.3.96
    
    • 1

    服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉

    => host = 172.22.3.1*,172.22.3.2*
    
    • 1

    源码分析


    ConditionRouter#route

    以下是条件路由的源码分析过程

    @Override
    public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation)
            throws RpcException {
       
        if (!enabled) {
       
            return invokers;
        }
    
        if (CollectionUtils.isEmpty(invokers)) {
       
            return invokers;
        }
        try {
       
          	// 先对服务消费者条件进行匹配,如果匹配失败,表明服务消费者 url 不符合匹配规则,
            // 无需进行后续匹配,直接返回 Invoker 列表即可
            if (!matchWhen(url, invocation)) {
       
                return invokers;
            }
            List<Invoker<T>> result = new ArrayList<Invoker<T>>();
          	// 服务提供者匹配条件未配置,表明对指定的服务消费者禁用服务,也就是服务消费者在黑名单中
            if (thenCondition == null) {
       
                logger.
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    从理论走向实战!阿里高工熬夜整理出的 Spring 源码速成笔记太香了
    数学基础之博弈论
    策略模式(设计模式)
    学习阶段单片机买esp32还是stm32?
    SQL题目记录
    ensp华为AC+AP上线配置
    【从互联网商业思维的角度分析商业模式在国内各大互联网产品的运用】
    在Domino上部署运行在Web浏览器中的Notes客户机
    元数据管理-解决方案调研三:元数据管理解决方案——开源解决方案
    【24种设计模式】单例模式(Singleton Pattern)
  • 原文地址:https://blog.csdn.net/qq_34561892/article/details/127909920