學習dubbo

一、基礎知識

1、分佈式基礎理論

1.1)、什麼是分佈式系統?

《分佈式系統原理與範型》定義:

“分佈式系統是若干獨立計算機的集合,這些計算機對於用戶來說就像單個相關係統”

分佈式系統(distributed system)是建立在網絡之上的軟件系統。

 

隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分佈式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。

1.2)、發展演變

 

單一應用架構

當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的數據訪問框架(ORM)是關鍵。

適用於小型網站,小型管理系統,將所有功能都部署到一個功能裏,簡單易用。

缺點: 1、性能擴展比較難

       2、協同開發問題

       3、不利於升級維護

 

垂直應用架構

當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。

通過切分業務來實現各個模塊獨立部署,降低了維護和部署的難度,團隊各司其職更易管理,性能擴展也更方便,更有針對性。

缺點: 公用模塊無法重複利用,開發性的浪費

分佈式服務架構

當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用於提高業務複用及整合的分佈式服務框架(RPC)是關鍵。

 

流動計算架構

當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集羣容量,提高集羣利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)[ Service Oriented Architecture]是關鍵

 

 

1.3)、RPC

什麼叫RPC

RPC【Remote Procedure Call】是指遠程過程調用,是一種進程間通信方式,他是一種技術的思想,而不是規範。它允許程序調用另一個地址空間(通常是共享網絡的另一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即程序員無論是調用本地的還是遠程的函數,本質上編寫的調用代碼基本相同。

RPC基本原理

RPC兩個核心模塊:通訊,序列化。

 

2、dubbo核心概念

2.1)、簡介

Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。

官網:

http://dubbo.apache.org/

2.2)、基本概念

http://dubbo.apache.org/img/architecture.png

服務提供者(Provider:暴露服務的服務提供方,服務提供者在啓動時,向註冊中心註冊自己提供的服務。

         服務消費者(Consumer: 調用遠程服務的服務消費方,服務消費者在啓動時,向註冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。

         註冊中心(Registry:註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者

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

  • 調用關係說明
  1. 服務容器負責啓動,加載,運行服務提供者。
  2. 服務提供者在啓動時,向註冊中心註冊自己提供的服務。
  3. 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
  4. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
  5. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
  6. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。

3、dubbo環境搭建

3.1)、【windows】-安裝zookeeper

1、下載zookeeper

網址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/

2、解壓zookeeper

解壓運行zkServer.cmd ,初次運行會報錯,沒有zoo.cfg配置文件

3、修改zoo.cfg配置文件

將conf下的zoo_sample.cfg複製一份改名爲zoo.cfg即可。

注意幾個重要位置:

dataDir=./   臨時數據存儲的目錄(可寫相對路徑)

clientPort=2181   zookeeper的端口號

修改完成後再次啓動zookeeper

4、使用zkCli.cmd測試

ls /:列出zookeeper根下保存的所有節點

create –e /atguigu 123:創建一個atguigu節點,值爲123

get /atguigu:獲取/atguigu節點的值

 

3.2)、【windows】-安裝dubbo-admin管理控制檯

dubbo本身並不是一個服務軟件。它其實就是一個jar包能夠幫你的java程序連接到zookeeper,並利用zookeeper消費、提供服務。所以你不用在Linux上啓動什麼dubbo服務。

但是爲了讓用戶更好的管理監控衆多的dubbo服務,官方提供了一個可視化的監控程序,不過這個監控即使不裝也不影響使用。

1、下載dubbo-admin

https://github.com/apache/incubator-dubbo-ops

 

2、進入目錄,修改dubbo-admin配置

修改 src\main\resources\application.properties 指定zookeeper地址

3、打包dubbo-admin

mvn clean package -Dmaven.test.skip=true

4、運行dubbo-admin

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

注意:【有可能控制檯看着啓動了,但是網頁打不開,需要在控制檯按下ctrl+c即可】

默認使用root/root 登陸

 

 

 

 

 

3.3)、【linux】-安裝zookeeper

1、安裝jdk

1、下載jdk

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

不要使用wget命令獲取jdk鏈接,這是默認不同意,導致下載來的jdk壓縮內容錯誤

2、上傳到服務器並解壓

3、設置環境變量

/usr/local/java/jdk1.8.0_171

文件末尾加入下面配置

export JAVA_HOME=/usr/local/java/jdk1.8.0_171

export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

export PATH=${JAVA_HOME}/bin:$PATH

4、使環境變量生效&測試JDK

 

2、安裝zookeeper

1、下載zookeeper

網址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/

wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz  

2、解壓

3、移動到指定位置並改名爲zookeeper

 

 

 

3、開機啓動zookeeper

1)-複製如下腳本

#!/bin/bash

#chkconfig:2345 20 90

#description:zookeeper

#processname:zookeeper

ZK_PATH=/usr/local/zookeeper

export JAVA_HOME=/usr/local/java/jdk1.8.0_171

case $1 in

         start) sh  $ZK_PATH/bin/zkServer.sh start;;

         stop)  sh  $ZK_PATH/bin/zkServer.sh stop;;

         status) sh  $ZK_PATH/bin/zkServer.sh status;;

         restart) sh $ZK_PATH/bin/zkServer.sh restart;;

         *)  echo "require start|stop|status|restart"  ;;

esac

 

 

2)-把腳本註冊爲Service

 

3)-增加權限

 

4、配置zookeeper

1、初始化zookeeper配置文件

拷貝/usr/local/zookeeper/conf/zoo_sample.cfg  

到同一個目錄下改個名字叫zoo.cfg

 

 

2、啓動zookeeper

 

3.4)、【linux】-安裝dubbo-admin管理控制檯

1、安裝Tomcat8(舊版dubbo-admin是war,新版是jar不需要安裝Tomcat)

1、下載Tomcat8並解壓

https://tomcat.apache.org/download-80.cgi

wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bin/apache-tomcat-8.5.32.tar.gz

2、解壓移動到指定位置

3、開機啓動tomcat8

複製如下腳本

#!/bin/bash

#chkconfig:2345 21 90

#description:apache-tomcat-8

#processname:apache-tomcat-8

CATALANA_HOME=/opt/apache-tomcat-8.5.32

export JAVA_HOME=/opt/java/jdk1.8.0_171

case $1 in

start)

    echo "Starting Tomcat..." 

    $CATALANA_HOME/bin/startup.sh

    ;;

 

stop)

    echo "Stopping Tomcat..." 

    $CATALANA_HOME/bin/shutdown.sh

    ;;

 

restart)

    echo "Stopping Tomcat..." 

    $CATALANA_HOME/bin/shutdown.sh

    sleep 2

    echo 

    echo "Starting Tomcat..." 

    $CATALANA_HOME/bin/startup.sh

    ;;

*)

    echo "Usage: tomcat {start|stop|restart}" 

    ;; esac

 

4、註冊服務&添加權限

5、啓動服務&訪問tomcat測試

 

2、安裝dubbo-admin

dubbo本身並不是一個服務軟件。它其實就是一個jar包能夠幫你的java程序連接到zookeeper,並利用zookeeper消費、提供服務。所以你不用在Linux上啓動什麼dubbo服務。

但是爲了讓用戶更好的管理監控衆多的dubbo服務,官方提供了一個可視化的監控程序,不過這個監控即使不裝也不影響使用。

1、下載dubbo-admin

https://github.com/apache/incubator-dubbo-ops

 

2、進入目錄,修改dubbo-admin配置

修改 src\main\resources\application.properties 指定zookeeper地址

3、打包dubbo-admin

mvn clean package -Dmaven.test.skip=true

4、運行dubbo-admin

java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

默認使用root/root 登陸

 

 

 

 

 

4、dubbo-helloworld

4.1)、提出需求

某個電商系統,訂單服務需要調用用戶服務獲取某個用戶的所有地址;

我們現在 需要創建兩個服務模塊進行測試

模塊

功能

訂單服務web模塊

創建訂單等

用戶服務service模塊

查詢用戶地址等

測試預期結果:

         訂單服務web模塊在A服務器,用戶服務模塊在B服務器,A可以遠程調用B的功能。

4.2)、工程架構

根據 dubbo《服務化最佳實踐》

1、分包

建議將服務接口,服務模型,服務異常等均放在 API 包中,因爲服務模型及異常也是 API 的一部分,同時,這樣做也符合分包原則:重用發佈等價原則(REP),共同重用原則(CRP)。

如果需要,也可以考慮在 API 包中放置一份 spring 的引用配置,這樣使用方,只需在 spring 加載過程中引用此配置即可,配置建議放在模塊的包目錄下,以免衝突,如:com/alibaba/china/xxx/dubbo-reference.xml。

2、粒度

服務接口儘可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。

服務接口建議以業務場景爲單位劃分,並對相近業務做抽象,防止接口數量爆炸。

不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會給後期維護帶來不便。

 

4.3)、創建模塊

1、gmall-interface:公共接口層(model,service,exception…)

作用:定義公共接口,也可以導入公共依賴

 

1、Bean模型

public class UserAddress implements Serializable{
    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String phoneNum;
    private String isDefault;

}

3、Service接口

UserService

public List<UserAddress> getUserAddressList(String userId)

 

2、gmall-user:用戶模塊(對用戶接口的實現)

1、pom.xml

  <dependencies>

    <dependency>

        <groupId>com.atguigu.dubbo</groupId>

        <artifactId>gmall-interface</artifactId>

        <version>0.0.1-SNAPSHOT</version>

    </dependency>

  </dependencies>

2、Service

public class UserServiceImpl implements UserService {

       

    @Override

    public List<UserAddress> getUserAddressList(String userId) {

        // TODO Auto-generated method stub

        return userAddressDao.getUserAddressById(userId);

    }

 

}

 

4、gmall-order-web:訂單模塊(調用用戶模塊)

1、pom.xml

<dependencies>

    <dependency>

        <groupId>com.atguigu.dubbo</groupId>

        <artifactId>gmall-interface</artifactId>

        <version>0.0.1-SNAPSHOT</version>

    </dependency>

   </dependencies>

2、測試

public class OrderService {

   

    UserService userService;

   

    /**

     * 初始化訂單,查詢用戶的所有地址並返回

     * @param userId

     * @return

     */

    public List<UserAddress> initOrder(String userId){

        return userService.getUserAddressList(userId);

    }

 

}

現在這樣是無法進行調用的。我們gmall-order-web引入了gmall-interface,但是interface的實現是gmall-user,我們並沒有引入,而且實際他可能還在別的服務器中。

4.4)、使用dubbo改造

1、改造gmall-user作爲服務提供者

1、引入dubbo

              <!-- 引入dubbo -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo</artifactId>

            <version>2.6.2</version>

        </dependency>

    <!-- 由於我們使用zookeeper作爲註冊中心,所以需要操作zookeeper

dubbo 2.6以前的版本引入zkclient操作zookeeper

dubbo 2.6及以後的版本引入curator操作zookeeper

下面兩個zk客戶端根據dubbo版本21即可

-->

        <dependency>

            <groupId>com.101tec</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.10</version>

        </dependency>

        <!-- curator-framework -->

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-framework</artifactId>

            <version>2.12.0</version>

        </dependency>

 

2、配置提供者

<!--當前應用的名字  -->

    <dubbo:application name="gmall-user"></dubbo:application>

    <!--指定註冊中心的地址  -->

    <dubbo:registry address="zookeeper://118.24.44.169:2181" />

    <!--使用dubbo協議,將服務暴露在20880端口  -->

    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 指定需要暴露的服務 -->

    <dubbo:service interface="com.atguigu.gmall.service.UserService" ref="userServiceImpl" />

3、啓動服務

    public static void main(String[] args) throws IOException {

        ClassPathXmlApplicationContext context =

                new ClassPathXmlApplicationContext("classpath:spring-beans.xml");

       

        System.in.read();

    }

 

 

2、改造gmall-order-web作爲服務消費者

1、引入dubbo

              <!-- 引入dubbo -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo</artifactId>

            <version>2.6.2</version>

        </dependency>

    <!-- 由於我們使用zookeeper作爲註冊中心,所以需要引入zkclientcurator操作zookeeper -->

        <dependency>

            <groupId>com.101tec</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.10</version>

        </dependency>

        <!-- curator-framework -->

        <dependency>

            <groupId>org.apache.curator</groupId>

            <artifactId>curator-framework</artifactId>

            <version>2.12.0</version>

        </dependency>

 

2、配置消費者信息

<!-- 應用名 -->

    <dubbo:application name="gmall-order-web"></dubbo:application>

    <!-- 指定註冊中心地址 -->

    <dubbo:registry address="zookeeper://118.24.44.169:2181" />

    <!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->

    <dubbo:reference id="userService" interface="com.atguigu.gmall.service.UserService"></dubbo:reference>

 

 

3、測試調用

訪問gmall-order-web的initOrder請求,會調用UserService獲取用戶地址;

調用成功。說明我們order已經可以調用遠程的UserService了;

 

 

4、註解版

1、服務提供方

    <dubbo:application name="gmall-user"></dubbo:application>

    <dubbo:registry address="zookeeper://118.24.44.169:2181" />

    <dubbo:protocol name="dubbo" port="20880" />

<dubbo:annotation package="com.atguigu.gmall.user.impl"/>

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

import com.atguigu.gmall.bean.UserAddress;

import com.atguigu.gmall.service.UserService;

import com.atguigu.gmall.user.mapper.UserAddressMapper;

 

@Service //使用dubbo提供的service註解,註冊暴露服務

public class UserServiceImpl implements UserService {

 

    @Autowired

UserAddressMapper userAddressMapper;

2、服務消費方

<dubbo:application name="gmall-order-web"></dubbo:application>

<dubbo:registry address="zookeeper://118.24.44.169:2181" />

<dubbo:annotation package="com.atguigu.gmall.order.controller"/>

 

@Controller

public class OrderController {

   

    @Reference  //使用dubbo提供的reference註解引用遠程服務

    UserService userService;

 

 

5、監控中心

5.1)、dubbo-admin

圖形化的服務管理頁面;安裝時需要指定註冊中心地址,即可從註冊中心中獲取到所有的提供者/消費者進行配置管理

 

5.2)、dubbo-monitor-simple

簡單的監控中心;

1、安裝

1、下載 dubbo-ops

https://github.com/apache/incubator-dubbo-ops

2、修改配置指定註冊中心地址

進入 dubbo-monitor-simple\src\main\resources\conf

修改 dubbo.properties文件

3、打包dubbo-monitor-simple

mvn clean package -Dmaven.test.skip=true

4、解壓 tar.gz 文件,並運行start.bat

如果缺少servlet-api,自行導入servlet-api再訪問監控中心

5、啓動訪問8080

 

2、監控中心配置

所有服務配置連接監控中心,進行監控統計

    <!-- 監控中心協議,如果爲protocol="registry",表示從註冊中心發現監控中心地址,否則直連監控中心 -->

    <dubbo:monitor protocol="registry"></dubbo:monitor>

 

Simple Monitor 掛掉不會影響到 Consumer 和 Provider 之間的調用,所以用於生產環境不會有風險。

Simple Monitor 採用磁盤存儲統計信息,請注意安裝機器的磁盤限制,如果要集羣,建議用mount共享磁盤。

 

6、整合SpringBoot

1、引入spring-boot-starter以及dubbo和curator的依賴

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.2.0</version>
</dependency>

注意starter版本適配:

 

2、配置application.properties

提供者配置:

dubbo.application.name=gmall-user
dubbo.registry.protocol=zookeeper
dubbo.registry.address=192.168.67.159:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo

application.name就是服務名,不能跟別的dubbo提供端重複

registry.protocol 是指定註冊中心協議

registry.address 是註冊中心的地址加端口號

protocol.name 是分佈式固定是dubbo,不要改。

base-package  註解方式要掃描的包

消費者配置:

dubbo.application.name=gmall-order-web
dubbo.registry.protocol=zookeeper
dubbo.registry.address=192.168.67.159:2181
dubbo.scan.base-package=com.atguigu.gmall
dubbo.protocol.name=dubbo

3、dubbo註解

@Service、@Reference

【如果沒有在配置中寫dubbo.scan.base-package,還需要使用@EnableDubbo註解】

 

 

 

 

二、dubbo配置

1、配置原則

JVM 啓動 -D 參數優先,這樣可以使用戶在部署和啓動時進行參數重寫,比如在啓動時需改變協議的端口。

XML 次之,如果在 XML 中有配置,則 dubbo.properties 中的相應配置項無效。

Properties 最後,相當於缺省值,只有 XML 沒有配置時,dubbo.properties 的相應配置項纔會生效,通常用於共享公共配置,比如應用名。

2、重試次數

失敗自動切換,當出現失敗,重試其它服務器,但重試會帶來更長延遲。可通過 retries="2" 來設置重試次數(不含第一次)。

重試次數配置如下:

<dubbo:service retries="2" />

<dubbo:reference retries="2" />

<dubbo:reference>

    <dubbo:method name="findFoo" retries="2" />

</dubbo:reference>

 

3、超時時間

由於網絡或服務端不可靠,會導致調用出現一種不確定的中間狀態(超時)。爲了避免超時導致客戶端資源(線程)掛起耗盡,必須設置超時時間。

1、Dubbo消費端

全局超時配置

<dubbo:consumer timeout="5000" />

 

指定接口以及特定方法超時配置

<dubbo:reference interface="com.foo.BarService" timeout="2000">

    <dubbo:method name="sayHello" timeout="3000" />

</dubbo:reference>

 

2、Dubbo服務端

全局超時配置

<dubbo:provider timeout="5000" />

 

指定接口以及特定方法超時配置

<dubbo:provider interface="com.foo.BarService" timeout="2000">

    <dubbo:method name="sayHello" timeout="3000" />

</dubbo:provider>

 

3、配置原則

dubbo推薦在Provider上儘量多配置Consumer端屬性:

1、作服務的提供者,比服務使用方更清楚服務性能參數,如調用的超時時間,合理的重試次數,等等

2、在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置可以作爲Consumer的缺省值。否則,Consumer會使用Consumer端的全局設置,這對於Provider不可控的,並且往往是不合理的

 

配置的覆蓋規則:

1) 方法級配置別優於接口級別,即小Scope優先

2) Consumer端配置 優於 Provider配置 優於 全局配置,

3) 最後是Dubbo Hard Code的配置值(見配置文檔)

 

4、版本號

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

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

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

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

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

老版本服務提供者配置:

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

 

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

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

 

 

三、高可用

1、zookeeper宕機與dubbo直連

現象:zookeeper註冊中心宕機,還可以消費dubbo暴露的服務。

原因:

健壯性

  1. 監控中心宕掉不影響使用,只是丟失部分採樣數據
  2. 數據庫宕掉後,註冊中心仍能通過緩存提供服務列表查詢,但不能註冊新服務
  3. 註冊中心對等集羣,任意一臺宕掉後,將自動切換到另一臺
  4. 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地緩存通訊
  5. 服務提供者無狀態,任意一臺宕掉後,不影響使用
  6. 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

 

高可用:通過設計,減少系統不能提供服務的時間;

2、集羣下dubbo負載均衡配置

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

負載均衡策略

Random LoadBalance

隨機,按權重設置隨機概率。

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

RoundRobin LoadBalance

輪循,按公約後的權重設置輪循比率。

存在慢的提供者累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。

LeastActive LoadBalance

最少活躍調用數,相同活躍數的隨機,活躍數指調用前後計數差。

使慢的提供者收到更少請求,因爲越慢的提供者的調用前後計數差會越大。

ConsistentHash LoadBalance

一致性 Hash,相同參數的請求總是發到同一提供者。

當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。算法參見:http://en.wikipedia.org/wiki/Consistent_hashing

缺省只對第一個參數 Hash,如果要修改,請配置 <dubbo:parameter key="hash.arguments" value="0,1" />

缺省用 160 份虛擬節點,如果要修改,請配置 <dubbo:parameter key="hash.nodes" value="320" />

 

3、整合hystrix,服務熔斷與降級處理

1、服務降級

什麼是服務降級?

當服務器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心交易正常運作或高效運作。

可以通過服務降級功能臨時屏蔽某個出錯的非關鍵服務,並定義降級後的返回策略。

向註冊中心寫入動態配置覆蓋規則:

RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();

Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));

registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));

 

其中:

  1. mock=force:return+null 表示消費方對該服務的方法調用都直接返回 null 值,不發起遠程調用。用來屏蔽不重要服務不可用時對調用方的影響。
  2. 還可以改爲 mock=fail:return+null 表示消費方對該服務的方法調用在失敗後,再返回 null 值,不拋異常。用來容忍不重要服務不穩定時對調用方的影響。

 

 

2、集羣容錯

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

集羣容錯模式

Failover Cluster

失敗自動切換,當出現失敗,重試其它服務器。通常用於讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設置重試次數(不含第一次)

 

重試次數配置如下:

<dubbo:service retries="2" />

<dubbo:reference retries="2" />

<dubbo:reference>

    <dubbo:method name="findFoo" retries="2" />

</dubbo:reference>

 

Failfast Cluster

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

 

Failsafe Cluster

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

 

Failback Cluster

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

 

Forking Cluster

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

 

Broadcast Cluster

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

 

集羣模式配置

按照以下示例在服務提供方和消費方配置集羣模式

<dubbo:service cluster="failsafe" />

<dubbo:reference cluster="failsafe" />

 

3、整合hystrix

Hystrix 旨在通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備擁有回退機制和斷路器功能的線程和信號隔離,請求緩存和請求打包,以及監控和配置等功能

1、配置spring-cloud-starter-netflix-hystrix

spring boot官方提供了對hystrix的集成,直接在pom.xml里加入依賴:

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

            <version>1.4.4.RELEASE</version>

        </dependency>

 

然後在Application類上增加@EnableHystrix來啓用hystrix starter:

@SpringBootApplication

@EnableHystrix

public class ProviderApplication {

 

 

2、配置Provider端

在Dubbo的Provider上增加@HystrixCommand配置,這樣子調用就會經過Hystrix代理。

@Service(version = "1.0.0")

public class HelloServiceImpl implements HelloService {

    @HystrixCommand(commandProperties = {

     @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),

     @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })

    @Override

    public String sayHello(String name) {

        // System.out.println("async provider received: " + name);

        // return "annotation: hello, " + name;

        throw new RuntimeException("Exception to show hystrix enabled.");

    }

}

 

3、配置Consumer端

對於Consumer端,則可以增加一層method調用,並在method上配置@HystrixCommand。當調用出錯時,會走到fallbackMethod = "reliable"的調用裏。

 

    @Reference(version = "1.0.0")

    private HelloService demoService;

 

    @HystrixCommand(fallbackMethod = "reliable")

    public String doSayHello(String name) {

        return demoService.sayHello(name);

    }

    public String reliable(String name) {

        return "hystrix fallback value";

    }

 

 

 

 

四、dubbo原理 

1、RPC原理

一次完整的RPC調用流程(同步調用,異步另說)如下:

1)服務消費方(client)調用以本地調用方式調用服務;

2client stub接收到調用後負責將方法、參數等組裝成能夠進行網絡傳輸的消息體;

3client stub找到服務地址,並將消息發送到服務端;

4server stub收到消息後進行解碼;

5server stub根據解碼結果調用本地的服務;

6)本地服務執行並將結果返回給server stub

7server stub將返回結果打包成消息併發送至消費方;

8client stub接收到消息,並進行解碼;

9)服務消費方得到最終結果。

RPC框架的目標就是要2~8這些步驟都封裝起來,這些細節對用戶來說是透明的,不可見的。

2、netty通信原理

Netty是一個異步事件驅動的網絡應用程序框架, 用於快速開發可維護的高性能協議服務器和客戶端。它極大地簡化並簡化了TCP和UDP套接字服務器等網絡編程。

BIO:(Blocking IO)

http://dl2.iteye.com/upload/attachment/0095/0307/04eebb37-3c6e-3e8f-9e30-66e24c57c47f.png

NIO (Non-Blocking IO)

http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/345fa2b327ec8a119ece0502286197d0

Selector 一般稱 爲選擇器 ,也可以翻譯爲 多路複用器,

Connect(連接就緒)、Accept(接受就緒)、Read(讀就緒)、Write(寫就緒)

Netty基本原理:

https://upload-images.jianshu.io/upload_images/3751588-8220ae4d80809f08.png?imageMogr2/auto-orient/

 

 

3、dubbo原理

1、dubbo原理 -框架設計

 

  1. config 配置層:對外配置接口,以 ServiceConfig, ReferenceConfig 爲中心,可以直接初始化配置類,也可以通過 spring 解析配置生成配置類
  2. proxy 服務代理層:服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton, 以 ServiceProxy 爲中心,擴展接口爲 ProxyFactory
  3. registry 註冊中心層:封裝服務地址的註冊與發現,以服務 URL 爲中心,擴展接口爲 RegistryFactory, Registry, RegistryService
  4. cluster 路由層:封裝多個提供者的路由及負載均衡,並橋接註冊中心,以 Invoker 爲中心,擴展接口爲 Cluster, Directory, Router, LoadBalance
  5. monitor 監控層:RPC 調用次數和調用時間監控,以 Statistics 爲中心,擴展接口爲 MonitorFactory, Monitor, MonitorService
  6. protocol 遠程調用層:封裝 RPC 調用,以 Invocation, Result 爲中心,擴展接口爲 Protocol, Invoker, Exporter
  7. exchange 信息交換層:封裝請求響應模式,同步轉異步,以 Request, Response 爲中心,擴展接口爲 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
  8. transport 網絡傳輸層:抽象 mina 和 netty 爲統一接口,以 Message 爲中心,擴展接口爲 Channel, Transporter, Client, Server, Codec
  9. serialize 數據序列化層:可複用的一些工具,擴展接口爲 Serialization, ObjectInput, ObjectOutput, ThreadPool

2、dubbo原理 -啓動解析、加載配置信息

3、dubbo原理 -服務暴露

4、dubbo原理 -服務引用

5、dubbo原理 -服務調用

 

 

 

 

 

 

 

發佈了26 篇原創文章 · 獲贊 24 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章