1. 程式人生 > >dubbo系列二:dubbo常用功能總結

dubbo系列二:dubbo常用功能總結

準備工作:

(1)啟動zookeeper作為dubbo的註冊中心

(2)新建一個maven的生產者web工程dubbo-provider-web和一個maven的消費者web工程dubbo-consumer-web

(3)在pom.xml檔案裡面引入如下依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
> <modelVersion>4.0.0</modelVersion> <groupId>com.study</groupId> <artifactId>dubbo-provider-web</artifactId> <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> <name>dubbo-provider-web Maven Webapp</name
> <url>http://maven.apache.org</url> <properties> <spring.version>4.3.10.RELEASE</spring.version> </properties> <dependencies> <!-- 新增dubbo依賴 --> <dependency> <groupId>com.alibaba</groupId
> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- 新增zk客戶端依賴 --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- spring相關 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <!-- 日誌相關依賴 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.10</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha2</version> </dependency> </dependencies> <build> <finalName>dubbo-provider-web</finalName> </build> </project>

1. 註解配置

dubbo可以使用註解在生產者端暴露服務介面和在消費端引用介面,只需要在生產者和消費者的配置檔案裡面配置掃描包路徑即可,而不用在xml裡面配置需要暴露和引用的介面

掃描包路徑的配置

<!-- 掃描註解包路徑,多個包用逗號分隔,不填pacakge表示掃描當前ApplicationContext中所有的類 -->
    <dubbo:annotation package="com.study.service" />

1.1 在生產者dubbo-provider-web和消費者dubbo-consumer-web新建一個dubbo註解測試的介面

package com.study.service;

/**
 * 
* @Description: dubbo註解測試的介面
* @author leeSmall
* @date 2018年10月23日
*
 */
public interface AnnotationDubboTest {
    public String eat(String param);
}

1.2 在生產者dubbo-provider-web新建一個dubbo註解測試的介面的實現類

package com.study.service;

import com.alibaba.dubbo.config.annotation.Service;

/**
 * 
* @Description: dubbo註解測試的介面的實現類
* @author leeSmall
* @date 2018年10月23日
*
 */
@Service(timeout = 1000000, version = "1.2.3")
public class AnnotationDubboTestImpl implements AnnotationDubboTest {
    
    public String eat(String param) {
        System.out.println("-----------AnnotationDubboTestImpl service test------------"
                + param);
        return "-----------AnnotationDubboTestImpl service test------------";
    }
    
}

1.3 在消費端dubbo-consumer-web新建一個測試的control

/**
 * 
 * @Description: dubbo消費端測試control
 * @author leeSmall
 * @date 2018年10月23日
 *
 */
@Controller
@RequestMapping("/common")
public class CommonController implements ApplicationContextAware {
    
    private static Logger logger = Logger.getLogger(CommonController.class);
    
    @Reference(check = false, timeout = 100000, version = "1.2.3")
    AnnotationDubboTest annotationdubbo;
    
    @RequestMapping("/annotationdubbo")
    public @ResponseBody String annotationdubbo() {
        annotationdubbo.eat("我是dubbo的註解測試control");
        return "annotationdubbo";
    }

}

1.4 在tomcat8080和tomcat8081分別啟動生產者和消費者,在瀏覽器輸入地址http://localhost:8081/dubbo-consumer-web/common/annotationdubbo訪問檢視效果

生產者端:

瀏覽器:

2. 啟動時檢查

Dubbo預設會在啟動時檢查依賴的服務是否可用,不可用時會丟擲異常,阻止Spring初始化完成,以便上線時,能及早發現問題,預設 check="true" 。可以通過 check="false" 關閉檢查,比如,測試時,有些服務不關心,或者出現了迴圈依賴,必須有一方先啟動。另外,如果你的Spring容器是懶載入的,或者通過API程式設計延遲引用服務,請關閉 check,否則服務臨時不可用時,會丟擲異常,拿到null引用,如果 check="false" ,總是會返回引用,當服務恢復時,能自動連上。

關閉某個服務的啟動時檢查 (沒有提供者時報錯):

<dubbo:reference interface="com.foo.BarService" check="false" />

關閉所有服務的啟動時檢查 (沒有提供者時報錯):

<dubbo:consumer check="false" />

3. 叢集容錯

3.1 Failover Cluster

失敗自動切換,預設值,當出現失敗,重試其它伺服器。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設定重試次數(不含第一次)。配置如下:生產者:<dubbo:service retries="2" />消費者:<dubbo:reference retries="2" /> 消費者具體到呼叫生產者的哪個方法:<dubbo:reference><dubbo:method name="findFoo" retries="2" /></dubbo:reference>

3.2 Failfast Cluster

快速失敗,只發起一次呼叫,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。配置如下:生產者:<dubbo:service cluster="failfast" /> 消費者:<dubbo:reference cluster="failfast" />

3.3 Failsafe Cluster

失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。配置如下:生產者:<dubbo:service cluster="failsafe" /> 消費者:<dubbo:reference cluster="failsafe" />

3.4 Failback Cluster

失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。配置如下:生產者:<dubbo:service cluster="failback" /> 消費者:<dubbo:reference cluster="failback" />

3.5 Forking Cluster

並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks="2" 來設定最大並行數。配置如下:生產者:<dubbo:service cluster=“forking" />消費者:<dubbo:reference cluster=“forking" />

3.6 Broadcast Cluster

廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯 。通常用於通知所有提供者更新快取或日誌等本地資源資訊。配置如下:生產者:<dubbo:service cluster="broadcast" />消費者:<dubbo:reference cluster="broadcast" />

4. 負載均衡

4.1 Random LoadBalance

隨機,按權重設定隨機概率。在一個截面上碰撞的概率高,但呼叫量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。

配置如下:

<dubbo:service interface="..." loadbalance="random" />
或:
<dubbo:reference interface="..." loadbalance="random" />
或:
<dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="random"/>
</dubbo:service>
或:
<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="random"/>
</dubbo:reference>

4.2 RoundRobin LoadBalance

輪循,按公約後的權重設定輪循比率。存在慢的提供者累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。

配置如下:

<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>

4.3 ConsistentHash LoadBalance

一致性 Hash,相同引數的請求總是發到同一提供者。當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。預設只對第一個引數 Hash,如果要修改,請配置 <dubbo:parameter key="hash.arguments"value="0,1" />預設用160份虛擬節點,如果要修改,請配置 <dubbo:parameter key="hash.nodes" value="320" />說明:hash.arguments:當進行呼叫時候根據呼叫方法的哪幾個引數生成key,並根據key來通過一致性hash演算法來選擇呼叫結點。例如呼叫方法invoke(String s1,String s2); 若hash.arguments為1(預設值),則僅取invoke的引數1(s1)來生成hashCode。hash.nodes:為結點的副本數

<dubbo:service interface="..." loadbalance="consistenthash" />
或:
<dubbo:reference interface="..." loadbalance="consistenthash" />
或:
<dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="consistenthash"/>
</dubbo:service>
或:
<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="consistenthash"/>
</dubbo:reference>

4.4 LeastActive LoadBalance

最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差。使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。

<dubbo:service interface="..." loadbalance="leastactive" />
或:
<dubbo:reference interface="..." loadbalance="leastactive" />
或:
<dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="leastactive"/>
</dubbo:service>
或:
<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="leastactive"/>
</dubbo:reference>

5. 服務分組

當一個介面有多個實現時,可以用group區分要呼叫的服務。

5.1 服務分組配置方式實現:

在生產者dubbo-provider-web和消費者dubbo-consumer-web分別新建一個介面

package com.study.test.service;

public interface DubboTestService {
    public String eat(String param);
}

在生產者dubbo-provider-web新建兩個DubboTestService介面的實現類

實現類1:

package com.study.test.service;

public class DubboTestServiceImpl implements DubboTestService {
    
    public String eat(String param) {
        
        System.out.println("-----------dubbo service test DubboTestServiceImpl ------------" + param);
        return "-----------dubbo service test DubboTestServiceImpl ------------";
    }
    
}

實現類2:

package com.study.test.service;

public class DubboTestService1Impl implements DubboTestService {
    
    public String eat(String param) {
        
        System.out.println("-----------dubbo service test DubboTestService1Impl------------" + param);
        return "-----------dubbo service test DubboTestService1Impl------------";
    }
    
}

在生產者dubbo-provider-web的applicationProvider.xml配置分組

    <!-- 服務分組 -->
    <bean id="dubboTestServiceImpl1" class="com.study.test.service.DubboTestServiceImpl"/>
    <bean id="dubboTestServiceImpl2" class="com.study.test.service.DubboTestService1Impl"/>
    <dubbo:service interface="com.study.test.service.DubboTestService" ref="dubboTestServiceImpl1" group="dubboTestServiceImpl1"/>
    <dubbo:service interface="com.study.test.service.DubboTestService" ref="dubboTestServiceImpl2" group="dubboTestServiceImpl2"/>

在消費者dubbo-consumer-web的applicationConsumer.xml配置呼叫的分組

    <!--服務分組  -->
    <dubbo