Dubbo學習筆記-RPC擴展和本地Mock


1.Dubbo介紹

Dubbo,一個是一款高性能Java RPC框架.私以為有中文官方文檔,就不再重復介紹了

2.RPC擴展-本地存根stub

RPC擴展功能:提前效驗參數,緩存調用結果,日志記錄等等,可以使用AOP織入這些擴展功能,但Dubbo提供了更靈活簡單的實現-本地存根stub。

3.本地Mock-本地偽裝mock

RPC在服務異常時,請求返回mock的(假)數據,而不是簡單的拋出異常,達到服務降級和本地mock的效果.只有在服務拋出異常時才會調用。

4.調用流程

  1. 服務消費者發起調用
  2. 如果服務消費者端存在本地存根 Stub 的話,會先執行本地存根
  3. 本地存根 Stub 持有遠程服務的 Proxy 對象,Stub 在執行的時候,會先執行自己的邏輯 (before),然后通過 Proxy 發起遠程調用,最后在返回過程之前也會執行自己的邏輯 (after-returning)
  4. 如果遠程服務的 Proxy 對象在執行過程中拋出了 exception,會執行服務消費端的本地偽裝 Mock 的邏輯 (after-throwing),返回容錯數據,從而達到服務降級的目的

5.本地存根實例

定義一個demo接口

public interface DemoService {
    String sayHello(String name);
}

根據約定大於配置原則,實現一個demo的stub實例

// 類名約定為 繼承接口+Stub
public class DemoServiceStub implements DemoService { 
    private static Logger logger = LoggerFactory.getLogger(DemoServiceStub.class);

    private final DemoService demoService;

    // 本地存根的實現需要提供一個拷貝構造方法,方便框架將遠程調用的 Proxy 對象注入進來
    public DemoServiceStub(DemoService demoService) {
        this.demoService = demoService;
    }

    // 本地存根需要提供服務接口中所有方法的實現。在本例中,需要實現 sayHello 方法
    @Override
    public String sayHello(String name) {
        // 進行預處理部分
        logger.info("before 執行遠程服務, 入參: " + name); 
        try {
            // 執行原函數功能,重要!!!
            String result = demoService.sayHello(name);
            // 執行函數后續部分,這里也可以完成緩存的操作
            logger.info("after 執行遠程服務, 出參: " + result);
            return result;
        } catch (Exception e) {
            // 異常處理部分
            logger.warn("執行失敗! ", e);
            return null;
        }
    }
}

在prvider.xml中將服務暴露出去

# resources\spring\mock-consumer.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方應用信息,用於計算依賴關系 -->
    <dubbo:application name="mock-demo-consumer"/>
    <dubbo:registry address="zookeeper://101.201.232.80:2181"/>
    <dubbo:metadata-report address="zookeeper://101.201.232.80:2181" />

    <!-- 用dubbo協議在本地20880端口通訊 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 和本地bean一樣實現服務 -->
    <bean id="demoService" class="mock.impl.DemoServiceImpl"/>

    <!-- 暴露接口類名遵循約定 -->
    <dubbo:reference id="demoService" check="false" interface="mock.api.DemoService" stub="true"/>
    <!-- 類名不遵循約定,則指定全類名 -->
    <!-- <dubbo:reference id="demoService" check="false" interface="mock.api.DemoService" stub="mock.api.DemoServiceStub"/> -->

</beans>

6.本地偽裝實例

dubbo默認為1000ms會拋超時異常,我們就讓線程sleep 5000ms來人為觸發
改造demo實現類如下,取消try則返回 hello + name,否則觸發mock,返回 mock + name

public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        try {
            // 默認為1s無響應則拋超時異常,此處睡眠5s,使其拋出異常
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello " + name;
    }
}

根據約定大於配置原則,實現一個demo的mock實例

// 類名:demo接口+Mock
public class DemoServiceMock implements DemoService {
    // 原服務拋出異常,則執行對應函數
    @Override
    public String sayHello(String name) {
        return "mock " + name;
    }
}

消費者xml需要稍微改造

# resources\spring\mock-consumer.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 消費方應用名,用於計算依賴關系,不是匹配條件,不要與提供方一樣 -->
    <dubbo:application name="mock-demo-consumer"/>

    <!--使用multicast廣播注冊中心暴露發現服務地址 30s耗時-->
    <dubbo:registry timeout="30000" address="zookeeper://127.0.0.1:2181"/>

    <!-- 生成遠程服務代理,可以和本地bean一樣使用demoService 注意mock=true-->
    <dubbo:reference id="demoService" check="false" interface="mock.api.DemoService"
                     mock="true"/>

</beans>

7.參考

  1. 本地存根Stub:https://github.com/apache/dubbo-samples/tree/master/java/dubbo-samples-stub
  2. 本地偽裝Mock:https://github.com/apache/dubbo-samples/tree/master/java/dubbo-samples-mock
  3. beiwei30:http://dubbo.apache.org/zh-cn/blog/dubbo-stub-mock.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM