dubbo學習筆記

目錄

 

一、dubbo簡介

二、dubbo環境搭建&快速啓動

三、dubbo配置

四、Dubbo執行過程

五、橫向對比

 


一、dubbo簡介

1.1 dubbo是什麼

dubbo是一款高性能、輕量級的開源Java RPC框架

1.2 dubbo主要功能

  • 面向接口的遠程方法調用

  • 智能容錯和負載均衡

  • 以及服務自動註冊和發現

1.3 dubbo結構

角色:註冊中心,服務提供者,服務消費者,dubbo框架容器,監控中心

dubbo啓動流程:

0)dubbo容器啓動,加載、運行服務提供者

1)服務提供者啓動時,向註冊中心註冊自己的服務

2)服務消費者啓動時,從註冊中心訂閱自己所需的服務

3)註冊中心返回服務提供者的地址列表給消費者,當服務提供者發生變化時;註冊中心將基於長連接推送變更數據給消費者

4)服務消費者基於軟負載均衡策略執行服務調用

5)服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心

1.4 dubbo發展歷程

獨家專訪阿里高級技術專家北緯:Dubbo開源重啓半年來的快意江湖

二、dubbo環境搭建&快速啓動

2.1 註冊中心(zookeeper)安裝 

wget http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz  #嫌慢的化可以直接下載附件
tar -zxvf zookeeper-3.4.14.tar.gz
cd zookeeper-3.4.14
cp conf/zoo_sample.cfg conf/zoo.cfg   #解壓包裏面只有zoo_sample.cfg,而沒有zoo.cfg,zookeeper的啓動依賴zoo.cfg
																			#按照自己需求配置zookeeper啓動屬性
 bash zkServer.sh start               #默認啓動端口爲2181

zookeeper-3.4.14.tar.gz

註冊中心

成熟度

優點

缺點

建議

Zookeeper註冊中心

Stable

支持基於網絡的集羣方式,有廣泛周邊開源產品,建議使用dubbo-2.3.3以上版本(推薦使用)

依賴於Zookeeper的穩定性

可用於生產環境

Redis註冊中心

Stable

支持基於客戶端雙寫的集羣方式,性能高

要求服務器時間同步,用於檢查心跳過期髒數據

可用於生產環境

Multicast註冊中心

Tested

去中心化,不需要安裝註冊中心

依賴於網絡拓撲和路由,跨機房有風險

小規模應用或開發測試環境

Simple註冊中心

Tested

Dogfooding,註冊中心本身也是一個標準的RPC服務

沒有集羣支持,可能單點故障

試用

2.2 dubbo管理控制檯安裝

SpringBoot + dubbo-admin-server + dubbo-admin-ui:(可選,不影響使用。安裝管理控制檯,可以可視化的管理服務)

  1. 下載管理控制檯 https://github.com/apache/incubator-dubbo-admin (springboot項目)

  2. 啓動dubbo-admin-server(後面需要在本地啓動服務提供中和服務消費者,爲了防止端口衝突,此處配置端口爲8888)

  3. 啓動dubbo-admin-ui,前端使用的是vue,需要Node環境

    nvm install 8.4.0
    nvm use 8.4.0
    cd dubbo-admin-ui
    npm install
    #更改config/index.js的target端口號爲8888(dubbo-admin-server配置的端口號)
    npm run dev
    #瀏覽器訪問localhost:8081

     

2.3 dubbo服務提供者

  1. pom.xml

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo-bom</artifactId>
            <version>2.6.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
    </dependencies>
  2. provider.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
           http://dubbo.apache.org/schema/dubbo
           http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
        <!--指定服務名字-->
        <dubbo:application name="hello-world-app"></dubbo:application>
        <!--指定註冊中心位置-->
        <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
        <!--指定通信規則-->
        <dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
        <!--暴露服務:interface指定接口名,ref指向實現類-->
        <dubbo:service interface="com.sankuai.api.HelloWorldService" ref="helloWorldService"></dubbo:service>
        <!--服務實現-->
        <bean id="helloWorldService" class="com.sankuai.impl.HelloWorldServiceImpl" ></bean>
    </beans>
  3. provider代碼

    3.1 HelloWorldService.java

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

    3.2 HelloWorldServiceImpl.java

    import com.sankuai.api.HelloWorldService;
    import org.springframework.stereotype.Service;
    
    @Service("helloWorldService")
    public class HelloWorldServiceImpl implements HelloWorldService {
    
        @Override
        public String sayHello(String name) {
            System.out.println("hello" + name);
            return "hello" + name;
        }
    }

    3.3 加載spring配置

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import java.io.IOException;
    public class Main {
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("provider.xml");
            ctx.start();
            System.in.read();
        }
    }

    3.4 在監控中心觀察到服務

2.4 dubbo消費者

  1. pom.xml

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo-bom</artifactId>
            <version>2.6.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <dependency>
            <groupId>com.sankuai</groupId>
            <artifactId>dubbo.studying</artifactId>
            <version>1.0-SNAPSHOT</version> 
        </dependency>
    </dependencies>
  2. consumer.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans        
                               http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        
                               http://dubbo.apache.org/schema/dubbo        
                               http://dubbo.apache.org/schema/dubbo/dubbo.xsd 
                               http://www.springframework.org/schema/context 
                               http://www.springframework.org/schema/context/spring-context.xsd">
        
        <context:component-scan base-package="com.sankuai.consumer.impl"></context:component-scan>
        <!--消費方appkey -->
        <dubbo:application name="consumer-of-helloworld-app"  />
        <!-- 註冊中心地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
        <!-- 指定需要使用的服務 -->
        <dubbo:reference id="helloWorldService" interface="com.sankuai.api.HelloWorldService" />
    </beans>
  3. consumer代碼

    3.1 Conmunicate.java

    public interface Conmunicate {
        String communicate(String name) ;
    }

    3.2 ConmunicateImpl.java

    import com.sankuai.api.HelloWorldService;
    import com.sankuai.consumer.api.Conmunicate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service("conmunicateService")
    public class ConmunicateImpl implements Conmunicate {
        @Autowired
        HelloWorldService helloWorldService;
    
        public String communicate(String name) {
            return helloWorldService.sayHello(name);
        }
    }

    3.3 加載spring配置,並調用遠程服務

    import com.sankuai.consumer.impl.ConmunicateImpl;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import java.io.IOException;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("consumer.xml");
            ConmunicateImpl conmunicate = (ConmunicateImpl) ctx.getBean("conmunicateService");
            String s = conmunicate.communicate("zhuyafeng");
            System.out.println(s);
            System.in.read();
        }
    }

    3.4 監控中心觀察消費者信息

2.5 dubbo監控中心安裝

  1. 下載管理控制中心(https://github.com/apache/dubbo-admin/tree/master)

三、dubbo配置

3.1 配置之間的依賴關係

3.2 dubbo標籤配置

標籤

用途

解釋

備註

<dubbo:service/>

服務配置

用於暴露一個服務,定義服務的元信息,一個服務可以用多個協議暴露,一個服務也可以註冊到多個註冊中心

 

<dubbo:reference/>

引用配置

用於創建一個遠程服務代理,一個引用可以指向多個註冊中心

引用缺省是延遲初始化的,只有引用被注入到其它 Bean,或被 getBean() 獲取,纔會初始化。如果需要飢餓加載,即沒有人引用也立即生成動態代理,可以配置:<dubbo:reference ... init="true" />

<dubbo:protocol/>

協議配置

用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受

 

<dubbo:application/>

應用配置

用於配置當前應用信息,不管該應用是提供者還是消費者

 

<dubbo:module/>

模塊配置

用於配置當前模塊信息,可選

 

<dubbo:registry/>

註冊中心配置

用於配置連接註冊中心相關信息

 

<dubbo:monitor/>

監控中心配置

用於配置連接監控中心相關信息,可選

 

<dubbo:provider/>

提供方配置

當 ProtocolConfig 和 ServiceConfig 某屬性沒有配置時,採用此缺省值,可選

 

<dubbo:consumer/>

消費方配置

當 ReferenceConfig 某屬性沒有配置時,採用此缺省值,可選

 

<dubbo:method/>

方法配置

用於 ServiceConfig 和 ReferenceConfig 指定方法級的配置信息

 

<dubbo:argument/>

參數配置

用於指定方法參數配置

 

 

3.3 常用dubbo配置(以xml配置爲例)

功能

功能

配置方式

備註

啓動時檢查

Dubbo 缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題,默認 check="true"

<dubbo:reference check="false> 關閉某個服務檢查

<dubbo:consumer check="false> 關閉所有服務檢查

<dubbo:register check="false"> 關閉註冊中心檢查

 

集羣容錯

在集羣調用失敗時,Dubbo 提供了多種容錯方案,缺省爲 failover 重試

集羣容錯模式 <dubbo:service cluster="failover" />

failover Cluster:失敗自動切換,當出現失敗,重試其它服務器

Failfast Cluster:快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。

Failsafe Cluster:失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。

Failback Cluster:失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於消息通知操作

Forking Cluster:並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。

 

默認爲failover,配合重試使用<dubbo:service retries="2" />(支持服務級,reference級和方法級配置)

負載均衡

在集羣負載均衡時,Dubbo 提供了多種均衡策略,缺省爲 random 隨機調用

服務端服務級別

<dubbo:service interface="..." loadbalance="roundrobin" />

客戶端服務級別

<dubbo:reference interface="..." loadbalance="roundrobin" />

服務端方法級別

<dubbo:service interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:service>

客戶端方法級別

<dubbo:reference interface="..."> <dubbo:method name="..." loadbalance="roundrobin"/> </dubbo:reference>

  1. 基於權重的隨機負載均衡機制(random LoadBalance) 默認

  2. 基於權重的輪詢負載均衡(RoundRobin LoadBalance)

  3. 基於最少活躍數負載均衡(LeastActive LoadBalance):選擇響應速度最快的

  4. 一致性哈希負載均衡 (consistentHash LoadBalance)

直連服務提供者

在開發及測試環境下,經常需要繞過註冊中心,只測試指定服務提供者,這時候可能需要點對點直連,點對點直連方式,將以服務接口爲單位,忽略註冊中心的提供者列表,A 接口配置點對點,不影響 B 接口從註冊中心獲取列表。

<dubbo:reference id="xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" />

不要在線上使用!!!

多協議暴露

Dubbo 允許配置多協議,在不同服務上支持不同協議或者同一服務上同時支持多種協議。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <dubbo:application name="world"  />
    <dubbo:registry id="registry" address="10.20.141.150:9090" username="admin" password="hello1234" />
    <!-- 多協議配置 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <dubbo:protocol name="hessian" port="8080" />
    <!-- 使用多個協議暴露服務 -->
    <dubbo:service id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" protocol="dubbo,hessian" />
</beans>

 

 

 

服務分組

當一個接口有多種實現時,可以用 group 區分

服務提供者

<dubbo:service group="feedback" interface="com.xxx.IndexService" />
<dubbo:service group="member" interface="com.xxx.IndexService" />

服務消費者

<dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" />
<dubbo:reference id="memberIndexService" group="member" interface="com.xxx.IndexService" />

dubbo2.2.0以上版本,服務消費者支持使用任意版本

<dubbo:reference id="barService" interface="com.foo.BarService" group="*" />

 

多版本

當一個接口實現,出現不兼容升級時,可以用版本號過渡,版本號不同的服務相互間不引用。

可以按照以下的步驟進行版本遷移:

  1. 在低壓力時間段,先升級一半提供者爲新版本

  2. 再將所有消費者升級爲新版本

  3. 然後將剩下的一半提供者升級爲新版本

老版本服務提供者配置:

<dubbo:service interface="com.foo.BarService" version="1.0.0" />

新版本服務提供者配置:

<dubbo:service interface="com.foo.BarService" version="2.0.0" />

老版本服務消費者配置:

<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />

新版本服務消費者配置:

<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />

如果不需要區分版本,可以按照以下的方式配置 [1]

<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />

 

Consumer只能消費與自己 “接口+分組+版本號” 一致的Provider提供的服務。

 

結果緩存

結果緩存 ,用於加速熱門數據的訪問速度,Dubbo 提供聲明式緩存,以減少用戶加緩存的工作量

接口級設置

<dubbo:reference interface="com.foo.BarService" cache="lru" />

方法級設置

<dubbo:reference interface="com.foo.BarService"> 
  <dubbo:method name="findBar" cache="lru" />
</dubbo:reference>

 

 

上下文信息

獲取當前RPC的上下文信息

// 本端是否爲消費端,這裏會返回true
boolean isConsumerSide = RpcContext.getContext().isConsumerSide();
// 獲取最後一次調用的提供方IP地址
String serverIP = RpcContext.getContext().getRemoteHost();
// 獲取當前服務配置信息,所有配置信息都將轉換爲URL的參數
String application = RpcContext.getContext().getUrl().getParameter("application");

 

 

provider異步執行

 

1.定義CompletableFuture簽名的接口

public interface AsyncService {
    CompletableFuture<String> sayHello(String name);
}

public class AsyncServiceImpl implements AsyncService {
    @Override
    public CompletableFuture<String> sayHello(String name) {
        RpcContext savedContext = RpcContext.getContext();
        // 建議爲supplyAsync提供自定義線程池,避免使用JDK公用線程池
        return CompletableFuture.supplyAsync(() -> {
            System.out.println(savedContext.getAttachment("consumer-key1"));
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "async response from provider.";
        });
    }
}

通過return CompletableFuture.supplyAsync(),業務執行已從Dubbo線程切換到業務線程,避免了對Dubbo線程池的阻塞。

2.使用AsyncContext

Dubbo提供了一個類似Serverlet 3.0的異步接口AsyncContext,在沒有CompletableFuture簽名接口的情況下,也可以實現Provider端的異步執行。

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

public class AsyncServiceImpl implements AsyncService {
    public String sayHello(String name) {
        final AsyncContext asyncContext = RpcContext.startAsync();
        new Thread(() -> {
            // 如果要使用上下文,則必須要放在第一句執行
            asyncContext.signalContextSwitch();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 寫回響應
            asyncContext.write("Hello " + name + ", response from provider.");
        }).start();
        return null;
    }
}

 

 

consumer異步調用

 

1.使用CompletableFuture簽名的接口,此方法依賴於服務提供者事先定義CompletableFuture簽名的服務

<dubbo:reference id="asyncService" timeout="10000" interface="com.alibaba.dubbo.samples.async.api.AsyncService"/>
// 調用直接返回CompletableFuture
CompletableFuture<String> future = asyncService.sayHello("async call request");
// 增加回調
future.whenComplete((v, t) -> {
    if (t != null) {
        t.printStackTrace();
    } else {
        System.out.println("Response: " + v);
    }
});
// 早於結果輸出
System.out.println("Executed before response return.");

 

2.使用RpcContext

<dubbo:reference id="asyncService" interface="org.apache.dubbo.samples.governance.api.AsyncService">
      <dubbo:method name="sayHello" async="true" />
</dubbo:reference>
// 此調用會立即返回null
asyncService.sayHello("world");
// 拿到調用的Future引用,當結果返回後,會被通知和設置到此Future
CompletableFuture<String> helloFuture = RpcContext.getContext().getCompletableFuture();
// 爲Future添加回調
helloFuture.whenComplete((retValue, exception) -> {
    if (exception == null) {
        System.out.println(retValue);
    } else {
        exception.printStackTrace();
    }
});

 

3. 利用Java 8提供的default接口實現,重載一個帶有帶有CompletableFuture簽名的方法

public interface GreetingsService {
    String sayHi(String name);
    
    // AsyncSignal is totally optional, you can use any parameter type as long as java allows your to do that.
    default CompletableFuture<String> sayHi(String name, AsyncSignal signal) {
        return CompletableFuture.completedFuture(sayHi(name));
    }
}

方法1是直接使用服務端實現的異步執行

 

方法2,3是在客戶端執行異步調用

 

 

Provider端異步執行和Consumer端異步調用是相互獨立的,你可以任意正交組合兩端配置

  • Consumer同步 - Provider同步

  • Consumer異步 - Provider同步

  • Consumer同步 - Provider異步

  • Consumer異步 - Provider異步

 

本地僞裝

本地僞裝通常用於服務降級,比如某驗權服務,當服務提供方全部掛掉後,客戶端不拋出異常,而是通過 Mock 數據返回授權失敗。

<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
package com.foo;
public class BarServiceMock implements BarService {
    public String sayHello(String name) {
        // 你可以僞造容錯數據,此方法只在出現RpcException時被執行
        return "容錯數據";
    }
}

 

 

本地僞裝

本地僞裝通常用於服務降級,比如某驗權服務,當服務提供方全部掛掉後,客戶端不拋出異常,而是通過 Mock 數據返回授權失敗。

<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
package com.foo;
public class BarServiceMock implements BarService {
    public String sayHello(String name) {
        // 你可以僞造容錯數據,此方法只在出現RpcException時被執行
        return "容錯數據";
    }
}

 

 

令牌驗證

通過令牌驗證在註冊中心控制權限,以決定要不要下發令牌給消費者,可以防止消費者繞過註冊中心訪問提供者,另外通過註冊中心可靈活改變授權方式,而不需修改或升級提供者

可以全局設置開啓令牌驗證:

<!--隨機token令牌,使用UUID生成--> <dubbo:provider interface="com.foo.BarService" token="true" />

<!--固定token令牌,相當於密碼--> <dubbo:provider interface="com.foo.BarService" token="123456" />

也可在服務級別設置:

<!--隨機token令牌,使用UUID生成--> <dubbo:service interface="com.foo.BarService" token="true" />

<!--固定token令牌,相當於密碼--> <dubbo:service interface="com.foo.BarService" token="123456" />

 

線程棧自動dump

當業務線程池滿時,我們需要知道線程都在等待哪些資源、條件,以找到系統的瓶頸點或異常點。dubbo通過Jstack自動導出線程堆棧來保留現場,方便排查問題

 

默認策略:

  • 導出路徑,user.home標識的用戶主目錄

  • 導出間隔,最短間隔允許每隔10分鐘導出一次

指定導出路徑:

# dubbo.properties dubbo.application.dump.directory=/tmp

<dubbo:application ...> <dubbo:parameter key="dump.directory" value="/tmp" /> </dubbo:application>

 

 

序列化

dubbo支持多種序列化方式,支持使用高效的Java序列化(Kryo和FST)

<dubbo:protocol name="dubbo" serialization="kryo"/>

<dubbo:protocol name="dubbo" serialization="fst"/>

性能:dubbo>hession2>json>java 其中dubbo序列化爲阿里自研,不建議生產環境使用

 

3.3 dubbo配置屬性的覆蓋策略

dubbo的屬性配置可以出現在狠多地方,關於這些配置的查找順序符合以下規則:

  • 方法級優先,接口級次之,全局配置再次之。

  • 如果級別一樣,則消費方優先,提供方次之。

四、Dubbo執行過程

4.1 服務註冊時序圖

 

 

 

4.2 服務發現時序圖

4.3 服務調用

 

 

五、橫向對比

5.1 各大互聯網公司使用的RPC框架

公司

RPC框架

阿里巴巴

HSF、Dubbo

騰訊

Tars

百度

brpc

美團點評

mtthrift(基於thrift)、pigeon

微博

Motan

京東

JSF(基於Dubbo)

網易考拉

Dubbok(基於Dubbo)

噹噹

Dubbox(基於Dubbo)

Google

grpc

Facebook

thrift

Twitter

finagle

5.2 pigeon&dubbo對比

 

Dubbo

pigeon

備註

開發語言

Java

Java

 

分佈式(服務治理)

dubbo monitor

pigeon

 

序列化方式

dubbo(基於hession2)、hession、json、jdk

fst、kryo

支持擴展

hessian、json、protobuf3、thrift、jdk

fst

支持擴展

 

註冊中心

zookeeper、redis、multicast、simple

zookeeper->mns(基於zookeeper)

 

跨編程語言

不支持

不支持

 

配置方式

註解配置、schema配置、api配置

註解配置、schema配置、屬性配置、api配置

 

服務通信協議

Dubbo 協議、 Rmi 協議、 Hessian 協議、 HTTP 協議、 WebService 協議、Dubbo Thrift 協議、Memcached 協議

HTTP協議,TCP協議

 

負載均衡

RandomLoadBalance (默認)、RoundRobinLoadBalance 、

ConsistentHash、LeastActive

WeightedAutoaware(默認,根據客戶端到服務節點的在途請求數,結合有效權重,重新計算請求容量,挑選請求容量最小的服務節點進行隨機負載)、Random、RoundRobin

 

服務容錯

Failover(默認策略,重試次數2)

Failfast(只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄)

Failsafe(失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作)

Failback (失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於消息通知操作)

Forking(調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設置最大並行數)

Broadcast(廣播調用所有提供者,逐個調用,任意一臺報錯則報錯 。通常用於通知所有提供者更新緩存或日誌等本地資源信息)

failfast(默認,失敗之後直接返回)

failover(失敗轉移策略,當調用一個節點失敗後,會調用另一個服務節點,重試次數默認爲-1,不顯示設置retry則不會重試)

failsafe(調用失敗後,不拋異常,會返回默認值null)

forking(並行策略,並行同時調用多個服務節點,以最先返回的結果爲最終結果返)

hedged(發起調用後,超過hedgedDelay時間後未返回結果,會再次向其他服務節點發送一個請求,以最先返回的結果爲結果返回,主要用在解決服務調用長尾問題)

 

 

服務調用方式

同步(默認,通過配置asyn屬性)

異步

oneway(通過方法裏面配置return=“false”屬性,同時可以使用sent="true"來等待消息發出,發送失敗則拋異常)

callback

 

事件通知:Consumer 端在調用之前、調用之後或出現異常時,觸發 oninvoke、onreturn、onthrow 三個事件。

<bean id="demoCallback" class="com.alibaba.dubbo.samples.notify.impl.NotifyImpl" />

<dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.samples.notify.api.DemoService" version="1.0.0" group="cn">
    <dubbo:method name="sayHello" onreturn="demoCallback.onreturn" onthrow="demoCallback.onthrow"/>
</dubbo:reference>

 

sync 默認

oneway 提交請求,無需等待,不需要返回結果

future 請求提交給pigeon後立即返回,不等待返回結果,由pigeon負責等待返回結果,客戶端可以自行決定何時何地來取返回結果

callback 回調方式,客戶端將請求提交給pigeon後立即返回,也不等待返回結果,它與future方式的區別是,callback必須提供一個實現了pigeon提供的ServiceCallback接口的回調對象給pigeon,pigeon負責接收返回結果並傳遞迴給這個回調對象

Pigeon 異步使用說明

其實不管是dubbo還是pigeon,同步調用的底層IO也是異步實現的。客戶端發起同步調用之後,會得到一個future對象,只不過同步調用的線程會阻塞到timeout,如果超時沒有還沒有返回,則返回調用失敗

 

調用方式判斷:DubboInvoker<T>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章