Dubbo 的 Multicast注冊中心有下面特點:
- 不需要啟動任何中心節點,只要廣播地址一樣,就可以互相發現
- 組播受網絡結構限制,只適合小規模應用或開發階段使用。
- 組播地址段: 224.0.0.0 - 239.255.255.255
有關組播的相關資料可以參考后面文章: http://www.cnblogs.com/ghj1976/p/5276452.html
廣播時的流程圖如下:
- 提供方啟動時廣播自己的地址。
- 消費方啟動時廣播訂閱請求。
- 提供方收到訂閱請求時,單播自己的地址給訂閱者,如果設置了unicast=false,則廣播給訂閱者。
- 消費方收到提供方地址時,連接該地址進行RPC調用。
我們用Wireshark來監控這個過程。
這時候的過濾條件是: ip.dst=224.0.0.0/4 這個ip地址段是廣播的地址段, 參考: http://stackoverflow.com/questions/11400046/wireshark-filter-by-multicast-in-gui
第一個發出的包,我們可以看到是注冊 UDP的包, 核心內容如下:
register dubbo://10.37.129.2:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&pid=3651&revision=2.5.4-SNAPSHOT&side=provider×tamp=1459131958710
隨后一個訂閱 UDP包。
subscribe provider://10.37.129.2:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&category=configurators&check=false&dubbo=2.5.4-SNAPSHOT&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&pid=3651&revision=2.5.4-SNAPSHOT&side=provider×tamp=1459131958710
當消費者啟動時,廣播了下面信息:
register consumer://10.37.129.2/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.5.4-SNAPSHOT&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=3803&revision=2.5.4-SNAPSHOT&side=consumer×tamp=1459134194229
subscribe consumer://10.37.129.2/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.5.4-SNAPSHOT&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=3803&revision=2.5.4-SNAPSHOT&side=consumer×tamp=1459134194229
通過這樣的方式,生產者和消費者都知道了對方,然后就是具體調用了。
具體調用,則是會返回下面2個內容的 TCP 包
2.5.4-SNAPSHOT0"com.alibaba.dubbo.demo.DemoService0.0.0sayHelloLjava/lang/String;world89Hpath0"com.alibaba.dubbo.demo.DemoService interface0"com.alibaba.dubbo.demo.DemoServiceversion0.0.0Z
08Hello world89, response form provider: 10.37.129.2:20880
這部分注冊的代碼,我們可以在 github/alibaba/dubbo/dubbo-registry/dubbo-registry-multicast/src/main/java/com/alibaba/dubbo/registry/multicast/MulticastRegistry.java 這里看到。
整個注冊相關的接口如下,這里只是提取 dubbo-registry-api 的其中 RegisterService 接口部分:
/**
* RegistryService. (SPI, Prototype, ThreadSafe)
*
* @see com.alibaba.dubbo.registry.Registry
* @see com.alibaba.dubbo.registry.RegistryFactory#getRegistry(URL)
* @author william.liangf
*/
public interface RegistryService {/**
* 注冊數據,比如:提供者地址,消費者地址,路由規則,覆蓋規則,等數據。
*
* 注冊需處理契約:<br>
* 1. 當URL設置了check=false時,注冊失敗后不報錯,在后台定時重試,否則拋出異常。<br>
* 2. 當URL設置了dynamic=false參數,則需持久存儲,否則,當注冊者出現斷電等情況異常退出時,需自動刪除。<br>
* 3. 當URL設置了category=routers時,表示分類存儲,缺省類別為providers,可按分類部分通知數據。<br>
* 4. 當注冊中心重啟,網絡抖動,不能丟失數據,包括斷線自動刪除數據。<br>
* 5. 允許URI相同但參數不同的URL並存,不能覆蓋。<br>
*
* @param url 注冊信息,不允許為空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
*/
void register(URL url);/**
* 取消注冊.
*
* 取消注冊需處理契約:<br>
* 1. 如果是dynamic=false的持久存儲數據,找不到注冊數據,則拋IllegalStateException,否則忽略。<br>
* 2. 按全URL匹配取消注冊。<br>
*
* @param url 注冊信息,不允許為空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
*/
void unregister(URL url);/**
* 訂閱符合條件的已注冊數據,當有注冊數據變更時自動推送.
*
* 訂閱需處理契約:<br>
* 1. 當URL設置了check=false時,訂閱失敗后不報錯,在后台定時重試。<br>
* 2. 當URL設置了category=routers,只通知指定分類的數據,多個分類用逗號分隔,並允許星號通配,表示訂閱所有分類數據。<br>
* 3. 允許以interface,group,version,classifier作為條件查詢,如:interface=com.alibaba.foo.BarService&version=1.0.0<br>
* 4. 並且查詢條件允許星號通配,訂閱所有接口的所有分組的所有版本,或:interface=*&group=*&version=*&classifier=*<br>
* 5. 當注冊中心重啟,網絡抖動,需自動恢復訂閱請求。<br>
* 6. 允許URI相同但參數不同的URL並存,不能覆蓋。<br>
* 7. 必須阻塞訂閱過程,等第一次通知完后再返回。<br>
*
* @param url 訂閱條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener 變更事件監聽器,不允許為空
*/
void subscribe(URL url, NotifyListener listener);/**
* 取消訂閱.
*
* 取消訂閱需處理契約:<br>
* 1. 如果沒有訂閱,直接忽略。<br>
* 2. 按全URL匹配取消訂閱。<br>
*
* @param url 訂閱條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @param listener 變更事件監聽器,不允許為空
*/
void unsubscribe(URL url, NotifyListener listener);/**
* 查詢符合條件的已注冊數據,與訂閱的推模式相對應,這里為拉模式,只返回一次結果。
*
* @see com.alibaba.dubbo.registry.NotifyListener#notify(List)
* @param url 查詢條件,不允許為空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
* @return 已注冊信息列表,可能為空,含義同{@link com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}的參數。
*/
List<URL> lookup(URL url);}
參考:http://dubbo.io/Multicast+Registry-zh.htm
為了減少廣播量,Dubbo缺省使用單播發送提供者地址信息給消費者,
如果一個機器上同時啟了多個消費者進程,消費者需聲明unicast=false,否則只會有一個消費者能收到消息:




