需求背景:
我們現在有一個服務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機器上面的服務