dubbo的路由规则
需求背景:
我们现在有一个服务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机器上面的服务