Duboo 不單讓我們可以像使用本地服務一樣的使用遠程服務,還設計了很多特性來滿足我們平時開發時常見的場景,省卻了我們不少麻煩,真是一款有良心的框架,下面針對這些場景和解決方案來具體解釋下:
1、接口與參數都可以加一些驗證,DUBBO自帶了
2、Dubbo提供聲明式緩存,以減少用戶加緩存的工作量
<dubbo:reference interface="com.foo.BarService" cache="lru" />
或
<dubbo:reference interface="com.foo.BarService">
<dubbo:method name="findBar" cache="lru" />
</dubbo:reference>
3、隱式傳參,由消費方設置,提供方獲取
RpcContext.getContext().setAttachment("index", "1"); // 隱式傳參,后面的遠程調用都會隱式將這些參數發送到服務器端,類似cookie,用於框架集成,不建議常規業務使用
String index = RpcContext.getContext().getAttachment("index"); // 獲取客戶端隱式傳入的參數,用於框架集成,不建議常規業務使用
4、異步調用,基於NIO的非阻塞實現並行調用,客戶端不需要啟動多線程即可完成並行調用多個遠程服務,相對多線程開銷較小。
<dubbo:reference id="fooService" interface="com.alibaba.foo.FooService">
<dubbo:method name="findFoo" async="true" />
</dubbo:reference>
fooService.findFoo(fooId); // 此調用會立即返回null
Future<Foo> fooFuture = RpcContext.getContext().getFuture();// 拿到調用的Future引用,當結果返回后,會被通知和設置到此Future
。 。。。。。//可進行多個類似上面的調用,相當於並發多個調用了
Foo foo = fooFuture.get(); // 如果foo已返回,直接拿到返回值,否則線程wait住,等待foo返回后,線程會被notify喚醒
。 。。。。。//都在等待各自結果的返回,以最長時間作為共需要的時間
如果你只是想異步,完全忽略返回值,可以配置return="false",以減少Future對象的創建和管理成本:
<dubbo:method name="findFoo" async="true" return="false" />
5、從 dubbo 2.2.0 開始,每個服務默認都會在本地暴露;在引用服務的時候,默認優先引用本地服務;如果希望引用遠程服務可以使用一下配置強制引用遠程服務。
<dubbo:reference ... scope="remote" />
6、本地存根,遠程服務后,客戶端通常只剩下接口,而實現全在服務器端,但提供方有些時候想在客戶端也執行部分邏輯,比如:做ThreadLocal緩存,提前驗證參數,調用失敗后偽造容錯數據等等,此時就需要在API中帶上Stub,客戶端生成Proxy實,會把Proxy通過構造函數傳給Stub,然后把Stub暴露組給用戶,Stub可以決定要不要去調Proxy。
<dubbo:service interface="com.foo.BarService" stub="true" />
com.foo.BarService
com.foo.BarServiceStub // 在API旁邊放一個Stub實現,它實現BarService接口,並有一個傳入遠程BarService實例的構造函數
BarServiceStub implements BarService public (BarService barService) ,代理模式
7、本地偽裝,服務提供方在客戶端執行容錯邏輯,因經常需要在出現RpcException(比如網絡失敗,超時等)時進行容錯,Mock就可以不依賴RpcException,因為它的約定就是只有出現RpcException時才執行,如果用Stub,可能就需要捕獲並依賴RpcException類 <dubbo:service interface="com.foo.BarService" mock="true" />
com.foo.BarService
com.foo.BarServiceMock // 在API旁邊放一個Mock實現,它實現BarService接口,並有一個無參構造函數
public String sayHello(String name) {
// 你可以偽造容錯數據,此方法只在出現RpcException時被執行
return "容錯數據";
}
如果服務的消費方經常需要try-catch捕獲異常,且想簡單的忽略異常,可改為Mock實現,節約代碼
<dubbo:service interface="com.foo.BarService" mock="return null" />
8、延遲暴露,如果你的服務需要Warmup時間,比如初始化緩存,等待相關資源就位等,可以使用delay進行延遲暴露。
<dubbo:service delay="5000" />
9、並發控制,限制服務器端或客戶端並發執行(或占用線程池線程數)不能超過10個
<dubbo:service interface="com.foo.BarService" executes="10" />
如果<dubbo:service>和<dubbo:reference>都配了actives,<dubbo:reference>優先
Load Balance均衡:
配置服務的客戶端的loadbalance屬性為leastactive,此Loadbalance會調用並發數最小的Provider
10、粘滯連接,用於有狀態服務,盡可能讓客戶端總是向同一提供者發起調用,除非該提供者掛了,再連另一台。
<dubbo:protocol name="dubbo" sticky="true" />
11、令牌驗證,當服務的權限改變,由注冊中心改變授權,不需修改服務代碼 在提供者上設置
<dubbo:provider interface="com.foo.BarService" token="true" />//也token="123456" ,相當於密碼
也可也服務級別設置
<dubbo:service interface="com.foo.BarService" token="true" />