由淺入深,一篇文章帶你讀懂Dubbo

1、基礎知識

一、分佈式基礎理論

1.1)什麼是分佈式系統

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

分佈式系統是若干獨立計算機的集合,這些計算機對於用戶來講就像單個相關係統(好比京東商城等)git

分佈式系統(distributed system)是創建在網絡之上的軟件系統程序員

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

1.2)、發展演變

由淺入深,一篇文章帶你讀懂Dubbo

  • 單一應用架構

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

由淺入深,一篇文章帶你讀懂Dubbo

單一應用架構有易於開發、易於測試、易於部署的優勢,可是也有很明顯的缺陷,那就是不易擴展、不易於協同開發,後期維護等缺陷spring

  • 垂直應用架構

當隨着應用規模不斷擴大,單體應用放在一個服務器上,那麼單臺服務器的壓力就扛不住了,這個時候就須要垂直應用架構。就是將單體應用架構拆分紅一個個小應用,並且每個應用都是完整的,當某一塊應用訪問量比較大時,就能夠多放幾臺服務器上。apache

由淺入深,一篇文章帶你讀懂Dubbo

優勢是分工合做容易,每一個人只負責本身的模塊,互不干擾,性能擴展容易等。缺點是界面和業務邏輯不能分離,不能徹底理想的獨立等缺點。windows

  • 分佈式服務架構

由淺入深,一篇文章帶你讀懂Dubbo

  • 流動計算架構

由淺入深,一篇文章帶你讀懂Dubbo

1.3)ROC

  • 什麼叫RPC

RPC[Remote Procedure Call]是指遠程過程調用,是一種進程間通訊方式。他是一種技術的思想,而不是規範。它容許程序調用另外一個地址空間(一般是共享網絡的另外一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即程序員不管是調用本地的仍是遠程的函數,本質上編寫的調用代碼基本相同。瀏覽器

由淺入深,一篇文章帶你讀懂Dubbo

由淺入深,一篇文章帶你讀懂Dubbo

RPC的核心就是起到一個網絡鏈接的做用,將倆個服務器進行通訊緩存

RPC框架有不少,如:dubbo、gRPC、Thrift、HSF等

二、dubbo核心概念及準備

  • 2.1)簡介

    Apache Dubbo(incubating)是一款高性能、輕量級的開源javaRPC框架、它提供了三大核心能力:面向接口的遠程調用,智能容錯和負載均衡,以及服務自動註冊和發展

  • 2.2)dubbo的前世此生

    Dubbo爲阿里巴巴公司開發一款高性能Java RPC框架

    其於2011年將其開源到GitHub上,可是在2014年10年月份,發佈其Dubbo2.4.11版本後,就中止更新了

    有不少公司在使用Dubbo,比較出名的有當當網在基於Dubbo的基礎上開發了自身的RPC框架DubboX;網易考拉也基於Dubbo開發了其自身的RPC框架DubboK

    2017年SpringCloud開始發力搶佔分佈式市場,阿里巴巴見此狀,又開始更新Dubbo

    2018年1月阿里巴巴將DubboX與Dubbo合併,發佈Dubbo2.6

    2018年2月15號,阿里巴巴將Dubbo貢獻給Apache

由淺入深,一篇文章帶你讀懂Dubbo

  • 2.3)dubbo的設計結構

由淺入深,一篇文章帶你讀懂Dubbo

  • 2.4)Zookeeper註冊中心

    在windows上安Zookeeper

    1. 下載Zookeeper.使用的版本爲zookeeper-3.4.11.tar.gz

    2. 解壓縮zookeeper-3.4.11.tar.gz

    3. 進入到zookeeper-3.4.11\conf目錄, 複製zoo_sample.cfg, 並從新命名我zoo.cfg

    4. 進入到zookeeper-3.4.11新建目錄data

    5. 修改zoo.cfg配置文件中dataDir配置項

    dataDir=../data

    1. 在cmd窗口中執行, 啓動zk

​ E:\zookeeper-3.4.11\bin>zkServer.cmd

​ 7.新開cmd窗口, 啓動zk客戶端驗證是否正常

​ E:\zookeeper-3.4.11\bin>zkCli.cmd

​ 8.列出節點, 建立新節點, 查詢特定節點的值

[zk: localhost:2181(CONNECTED) 2] ls /   列出節點
[zookeeper]
[zk: localhost:2181(CONNECTED) 3] create -e /atguigu 123456   建立節點
Created /atguigu
[zk: localhost:2181(CONNECTED) 4] ls /
[zookeeper, atguigu]
[zk: localhost:2181(CONNECTED) 5] get /atguigu  查詢特定節點的值
123456
cZxid = 0x2
ctime = Sun Aug 11 15:24:52 CST 2019
mZxid = 0x2
mtime = Sun Aug 11 15:24:52 CST 2019
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100c7723f2b0000
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 6]
  • 2.5)環境搭建

從https://github.com/locationbai/incubator-dubbo-ops-master上clone下源碼,而後進入到incubator-dubbo-ops-master-master\dubbo-admin目錄中,修改

incubator-dubbo-ops-master-master\dubbo-admin\src\main\resources目錄下的application.properties文件內容(主要是Zookeeper的地址要正確)

server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guest

dubbo.registry.address=zookeeper://127.0.0.1:2181

從源碼構建出admin的jar包

mvn clean package

而後經過java命令運行build出的jar包

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

而後經過瀏覽器訪問

http://localhost:7001

用帳戶名稱root,密碼爲root進行登陸

由淺入深,一篇文章帶你讀懂Dubbo

三、dubbo實現

  • 3.1)建立提供消費者工程

由淺入深,一篇文章帶你讀懂Dubbo

由淺入深,一篇文章帶你讀懂Dubbo

搭建gmall-interface項目用於存放公共的bean和接口

搭建order-service-consumer做爲服務消費者

搭建user-service-provider做爲服務提供者

由淺入深,一篇文章帶你讀懂Dubbo

  • 3.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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--當前項目在整個分佈式架構裏面的惟一名稱,計算依賴關係的標籤-->
    <dubbo:application name="provider"></dubbo:application>

    <!-- 使用multicast廣播註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!--當前服務發佈所依賴的協議;webserovice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--服務發佈的配置,須要暴露的服務接口-->
    <dubbo:service interface="com.yueyue.service.UserService" ref="providerService"/>

    <!--Bean bean定義-->
    <bean id="providerService" class="com.yueyue.service.impl.UserServiceImpl"/>

</beans>

啓動類MainApplication:

public static void main(String[] args) throws IOException {
        //加載xml配置文件啓動
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
        context.start();
        System.in.read(); // 按任意鍵退出
    }

pom.xml進行架包的依賴及管理

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>user-service-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

由淺入深,一篇文章帶你讀懂Dubbo

這裏注意看下結構,不要放亂了。

  • 3.3)服務消費者配置

consimer.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="order-service-consumer"  />

    <!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService -->
    <dubbo:reference id="UserService" interface="com.yueyue.service.UserService" />
</beans>

主啓動方法:

public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");
        OrderService orderService = context.getBean(OrderService.class);
        orderService.initOrder("1");
        System.in.read();
    }

pom.xml架包依賴及管理

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>order-service-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

由淺入深,一篇文章帶你讀懂Dubbo

  • 3.4)抽取公共bean和接口

    OrderService接口:

public interface OrderService {
    void initOrder(String userId);
}

UserService接口:

public interface UserService {
    List<UserAddress> getUserAddressList(String userId);
}

由淺入深,一篇文章帶你讀懂Dubbo

四、dubbo與springboot整合

當服務提供者和服務消費者均基於SpringBoot來作開發的話,其配置形式與上面普通的基於Spring的項目來講不一樣之處在於:

  1. 導入Dubbo基於SpringBoot的starter
<dependency>
   <groupId>com.alibaba.boot</groupId>
   <artifactId>dubbo-spring-boot-starter</artifactId>
   <version>0.2.0</version>
</dependency>
  1. 在SpringBoot中經過application.properties配置文件代替Spring項目中的xml配置文件
服務提供者配置示例以下
dubbo.application.name=user-service-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper

dubbo.protocol.name=dubbo
dubbo.protocol.port=20881

dubbo.monitor.protocol=registry
服務消費者配置示例以下
server.port=8081

dubbo.application.name=boot-order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry
  1. 服務提供者經過Dubbo中的@Service註解進行體現
@Service//暴露服務 
@Component
public class UserServiceImpl implements UserService
  1. 服務消費者引用服務提供者的須要用@Reference體現
@Service
public class OrderServiceImpl implements OrderService {

   //@Autowired
   @Reference
   UserService userService;

五、dubbo配置

  • 5.1)配置dubbo.properties&屬性加載順序

由淺入深,一篇文章帶你讀懂Dubbo

相同的配置若是出如今三個位置,優先級從上往下逐漸下降(最上面的覆蓋最下邊的)

  1. 若是項目是基於Spring來作的開發,那麼優先級順序爲:

    -D > dubbo.xml > dubbo.properties

  2. 若是項目是基於SpringBoot來作的開發,那麼優先級爲:

    -D > application.properties > dubbo.properties

  • 5.2)配置啓動檢查

在默認的狀況下,當服務調用者項目啓動的時候會自動檢查要調用的服務是否正常,若是被調用的服務不正常的話,其本身就會啓動失敗。爲了讓項目能正常啓動,而不去檢查所依賴的服務是否正常,能夠關閉服務檢查。下面的配置片斷就是在服務消費者consumer.xml中關閉了服務檢查

<context:component-scan base-package="com.atguigu.gmall.service.impl"></context:component-scan>

<dubbo:application name="order-service-consumer"></dubbo:application>

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

<!--  配置本地存根-->

<!--聲明須要調用的遠程服務的接口;生成遠程服務代理  -->
<!-- 
   1)、精確優先 (方法級優先,接口級次之,全局配置再次之)
   2)、消費者設置優先(若是級別同樣,則消費方優先,提供方次之)
-->
<!-- timeout="0" 默認是1000ms-->
<!-- retries="":重試次數,不包含第一次調用,0表明不重試-->
<!-- 冪等(設置重試次數)【查詢、刪除、修改】、非冪等(不能設置重試次數)【新增】 -->
<dubbo:reference interface="com.atguigu.gmall.service.UserService" 
   id="userService" timeout="5000" retries="3" version="*">
   <!-- <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> -->
</dubbo:reference>

<!-- 配置當前消費者的統一規則:全部的服務都不檢查 -->
<dubbo:consumer check="false" timeout="5000"></dubbo:consumer>

<!--<dubbo:monitor protocol="registry"></dubbo:monitor>-->
 <dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>
  • 5.3)配置超時&配置覆蓋關係

當服務消費者調用服務提供者服務的時候,會存在超時的狀況;而Dubbo提供爲服務消費者設置調用服務提供者服務的超時時間,也提供了服務提供者爲其自身提供的服務設置超時時間;

對於服務提供者和服務消費者Dubbo均提供瞭如下四種粒度的設置

​ 1 .方法級別

  1. 接口級別

  2. 服務消費者級別

  3. 服務提供者級別

由淺入深,一篇文章帶你讀懂Dubbo

  • 5.4)配置_重試次數
<!-- timeout="0" 默認是1000ms-->
<!-- retries="":重試次數,不包含第一次調用,0表明不重試-->
<!-- 冪等(設置重試次數)【查詢、刪除、修改】、非冪等(不能設置重試次數)【新增】 -->
<dubbo:reference interface="com.atguigu.gmall.service.UserService" 
<!-- 調用userService失敗後會重試3次,加上第一次的調用,若調用一直失敗的話,總共會調用4次-->
   id="userService" timeout="5000" retries="3" version="*">
<!-- <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> -->
</dubbo:reference>
  • 5.5)配置_多版本

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

能夠按照如下的步驟進行版本遷移(經過視頻的演示發現,Dubbo對於多版本的支持的易用性上作得很是好)

  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="*" />
  • 5.6)配置_本地存根

一般狀況才採用遠程服務調用後,對於服務消費者的請求,均是在服務提供者的遠程機器上執行的!經過採用本地存根的形式就能夠將服務消費者請求的一些驗證操做在其本地進行執行,這樣就減小了網絡的傳輸,提升了執行效率

  • 5.7)與springboot的三種整合方式

第一種方式:

註解的方式:在java類上使用Dubbo提供的註解

第二種方式:

配置文件方式:在xml配置文件中對Dubbo進行配置,包括服務應用的名稱配置,註冊中心配置,通訊規則,服務提供者信息,服務消費者信息等

第三種方式:

Java Config方法:經過java配置類(在一個java類上使用@Configuration註解)的方式配置註冊中心,通訊規則,服務提供者信息,服務消費者信息等

六、高可用

6.1)zookeeper宕機與dubbo直連

由淺入深,一篇文章帶你讀懂Dubbo

採用Dubbo進行微服務的架構,若使用Zookeeper做爲註冊中心的話,當註冊中心宕機時,是不影響服務調用的,由於關於服務調用的信息,在服務消費者和服務提供者本地有緩存

Dubbo也提供了直連的方式,使服務調用的雙方直接進行通訊,從而能夠繞過註冊中心

6.2)負載均衡機制

負載均衡策略

Random LoadBalance

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

RoundRobin LoadBalance

  • 輪詢,按公約後的權重設置權重輪詢比率。
  • 存在慢的提供者積累請求的問題,好比:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,長此以往,全部請求都卡在調到第二臺上。

LeastActive LoadBalance

  • 最少活躍調用數,相同活躍的隨機,活躍數指調用後計數差。
  • 使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。

ConsistentHash LoadBalance

  • 一致性Hash,相同參數的請求老是發到同一提供者。
  • 當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其餘提供者,不會引發劇烈變更。

由淺入深,一篇文章帶你讀懂Dubbo

6.3)服務降級

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

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

6.4)服務容錯

Dubbo有本身的容錯機制,以下:

Failfast Cluster

快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的操做,好比新增記錄。

Failsafe Cluster

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

Faiback Cluster

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

Forking Cluster

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

Broadcast Cluster

廣播調用全部提供者,逐個調用,任意一臺報錯則報錯。一般用於通知全部提供者更新緩存或日誌等本地資源信息。

若是是採用Dubbo微服務框架的話,能夠直接使用Dubbo提供的上面的容錯功能

若是項目採用了Dubbo做爲微服務框架時,在項目中也可使用Hystrix

七、Dubbo原理

7.1)RPC原理

由淺入深,一篇文章帶你讀懂Dubbo

一次完整的RPC調用流程(同步調用,異步另說)以下:
1)服務消費方(client)調用以本地調用方法調用服務;
2)client stub接收到調用後負責將方法、參數等組裝成可以進行網絡傳輸的消息體;
3)client stub找到服務地址,並將消息發送到服務端;
4)server stub收到消息後解碼;
5)server stub根據解碼結果調用本地的服務;
6)本地服務執行並將結果返回給server stub
7)server stub將返回結果打包成消息併發送至消費方
8)client stub接收到消息,並進行解碼
9)服務消費方獲得最終結果
RPC框架的目標就是要2-8這些步驟都封裝起來,這些細節對用戶來講是透明的,不可見的。

7.2)nrtty通訊原理

由淺入深,一篇文章帶你讀懂Dubbo

由淺入深,一篇文章帶你讀懂Dubbo

由淺入深,一篇文章帶你讀懂Dubbo

7.3)Dubbo框架總體設計

由淺入深,一篇文章帶你讀懂Dubbo

7.4)標籤解析

由淺入深,一篇文章帶你讀懂Dubbo

7.5)服務暴露流程

簡單來講Dubbo進行服務暴露的流程以下:

  1. 當項目啓動的時候Dubbo首先經過DubboBeanDefinitionParser來解析xml配置文件(在本例中爲provider.xml)。解析信息就是xml配置的xml元素,例如服務提供者實現的接口信息,註冊中心信息等

  2. 當解析完xml配置文件後,有兩種信息尤其關鍵,一個是ServiceBean,一個是ServiceConfig

  3. 經過ServiceBean提供的信息(服務提供者相關的一些信息,服務的訪問地址等)Dubbo在底層會啓動Netty服務器從而監聽在此ServiceBean中的服務配置的地址和端口上

  4. 在啓動Netty服務器的同時,Dubbo會根據ServiceConfig信息將服務提供者的信息註冊到配置中心(Zookeeper中)

  5. 最終根據服務提供者的信息Dubbo不只啓動了Netty服務器,也將該服務提供者的信息註冊進了配置中心(Zookeeper),也在本地的providerInvokers中保存了服務提供者的信息

由淺入深,一篇文章帶你讀懂Dubbo

7.6)服務引用流程

下圖爲Dubbo服務消費者調用遠程服務的流程。大致上與Dubbo進行服務暴露的流程是類似的

由淺入深,一篇文章帶你讀懂Dubbo

7.7)服務調用流程

服務消費者調用服務提供者的流程簡單來講就是,服務消費者經過配置中心獲取到服務提供者相關的信息後,首先進行一些Filter(下圖中的local,mock,cache判斷。例如cache服務消費者是否啓用了緩存功能)。

而後進行服務調用(一般底層是經過客戶端的方式與服務器端進行通訊。經常使用的客戶端經過下圖能夠看出有Netty,mina等)

由淺入深,一篇文章帶你讀懂Dubbo

相關文章
相關標籤/搜索