首页 > 技术文章 > dubbo的路由规则

pengyonglei 2017-12-08 16:24 原文

需求背景: 

  我们现在有一个服务A, 需要暴露在同一个zookeeper上面, 但是注册到zookeeper的地址需要有公网和内网两种, 但是我又不想在代码中做修改. 

需求说明: 

  同一个服务需要提供内网和公网地址的原因是: 我们有服务B所在的机器只能通过外网去访问服务A, 但是外网访问会受到带宽的限制. 但是服务A的请求量又恨大, 因此, 我就希望除了服务B以外的机器都通过内网去访问服务A, 这样就解决了带宽上面的限制. 

  但是, 服务A的集群是在同一个zookeeper下面的. 所以, 我就必须指定服务B去访问服务A的外网地址的dubbo服务.

  这里有一个方案: 就是我使用两个不同的zookeeper, 外网地址的服务A注册到zookeeper-1上面, 内网地址的注册到zookeeper-2上面. 这样也是可以解决上面指定服务B访问服务A的问题. 

  但是, 我们上了监控, 监控是监控一个zookeeper地址的服务, 所以, 我就不能有多个zookeeper, 这样会加大复杂度. 这个时候, 我就去dubbo 文档调研了一下, 发现了 路由规则 这样的好东西

解决方案:

  我先去调研了一下负载均衡, 但是发现负载均衡无法解决我现在的问题. 因为我需要让服务B指定消费服务A的外网地址注册 . 

  然后我在很绝望的情况下, 发现了 路由规则这个配置. 路由规则配置官网文档

  具体的配置, 文档上面写的很清楚, 我指出一些问题和细节. 

问题:

1. 文档上面关于runtime=false的默认值是错误的. 

 

源码里面是如果dynamic为null的时候, 默认值为true. 这个地方是文档有问题

 

2. 关于路由规则示例代码出现的问题: 

这个地方的 `+ "` 是多余的. 还是希望文档严谨一点啊. 

  

 

说完文档上面的问题之后, 我来说说细节问题:

1. 关于不小心写错路由规则, 然后在dubbo-admin无法删除的问题. 

这个问题, 我们需要自己去zookeeper的控制台去删除.  在zookeeper的bin目录里面有zkCli.sh 命令. 进入, 我们可以查看到节点, 然后去删除router. 

PS: windows系统, 可以直接执行zkCli.cmd

 使用 `ls2 /dubbo` 可以查看到dubbo的所有服务.  我查看我测试的服务: `ls2 /dubbo/dubbo.test.interfaces.TestService`

可以看到 四个节点. 我们进入 routers . 看到路由的规则

然后执行delete /dubbo/dubbo.test.interfaces.TestService/routers/<路由规则名称>. 

如果删除不了. 可以直接使用 rmr /dubbo/dubbo.test.interfaces.TestService/routers 将整个节点删除. 这样dubbo-admin上面也会被删除掉

 2. 如何对多个服务注册路由规则

目前, 我使用下来的是注册两遍. 如下图: 

以上就是我使用下来, 觉得文档上面没有说明白的地方. 做一个补充. 

 

PS: 脚本路由规则没有尝试过, 后面有时间再试试. 用过的同学也可以给我分享一下哈. 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2017年12月15日 对路由规则测试的补充:

priority : 路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为 0 [官方文档解释]

测试下来的结果: 我们可以使用这个参数达到对同一个服务设置多个路由规则的效果. 

举例说明: 

服务名称: dubbo.test.interfaces.TestService[集群状态, 有多台机器]

规则: 

路由规则-1 : 禁止所有消费者访问主机 192.168.0.101上的服务.
路由规则-2 : 指定 application = dubbo.test.consumer-1 的消费者 访问 主机192.168.0.101上面的服务
1 registry.register(URL.valueOf("condition://0.0.0.0/dubbo.test.interfaces.TestService?category=routers&name=路由规则-1&dynamic=true&priority=2&enabled=true&rule=" + URL.encode(" => host != 192.168.0.101")));
2 
3 registry.register(URL.valueOf("condition://0.0.0.0/dubbo.test.interfaces.TestService?category=routers&name=路由规则-2&dynamic=true&priority=1&enabled=true&rule=" + URL.encode("application = dubbo.test.consumer-1 => host = 192.168.0.101")));

由于路由规则-1优先级比路由规则-2高, 所以先执行路由规则-1, 再执行路由规则-2. 

这样就可以达到我们的目标: 指定消费者消费A机器上面的服务, 而让其他消费者不消费A机器上面的服务

 

推荐阅读