Dubbo 2.7.7 學(xué)習(xí)筆記 1

Dubbo 2.7.7 起步入門學(xué)習(xí)筆記

本文檔基于 Dubbo 中文官方文檔編寫,詳情請(qǐng)參見 Dubbo 中文官方文檔

Dubbo 產(chǎn)生的背景

隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大,常規(guī)的垂直應(yīng)用架構(gòu)已無法應(yīng)對(duì),分布式服務(wù)架構(gòu)以及流動(dòng)計(jì)算架構(gòu)勢(shì)在必行,亟需一個(gè)治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)。

image

單一應(yīng)用架構(gòu)

當(dāng)網(wǎng)站流量很小時(shí),只需一個(gè)應(yīng)用,將所有功能都部署在一起,以減少部署節(jié)點(diǎn)和成本。此時(shí),用于簡化增刪改查工作量的數(shù)據(jù)訪問框架 (ORM) 是關(guān)鍵。

垂直應(yīng)用架構(gòu)

當(dāng)訪問量逐漸增大,單一應(yīng)用增加機(jī)器帶來的加速度越來越小,提升效率的方法之一是將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用,以提升效率。此時(shí),用于加速前端頁面開發(fā)的 Web 框架 (MVC) 是關(guān)鍵。

分布式服務(wù)架構(gòu)

當(dāng)垂直應(yīng)用越來越多,應(yīng)用之間交互不可避免,將核心業(yè)務(wù)抽取出來,作為獨(dú)立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心,使前端應(yīng)用能更快速的響應(yīng)多變的市場需求。此時(shí),用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架 (RPC) 是關(guān)鍵。

流動(dòng)計(jì)算架構(gòu)

當(dāng)服務(wù)越來越多,容量的評(píng)估,小服務(wù)資源的浪費(fèi)等問題逐漸顯現(xiàn),此時(shí)需增加一個(gè)調(diào)度中心基于訪問壓力實(shí)時(shí)管理集群容量,提高集群利用率。此時(shí),用于提高機(jī)器利用率的資源調(diào)度和治理中心 (SOA) 是關(guān)鍵。

Dubbo 的架構(gòu)

dubbo-architucture

各節(jié)點(diǎn)的說明

節(jié)點(diǎn) 角色說明
Provider 暴露服務(wù)的服務(wù)提供方
Consumer 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
Registry 服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心
Monitor 統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心
Container 服務(wù)運(yùn)行容器

調(diào)用關(guān)系說明

  1. 服務(wù)容器負(fù)責(zé)啟動(dòng),加載,運(yùn)行服務(wù)提供者。

  2. 服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù)。

  3. 服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù)。

  4. 注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者。

  5. 服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。

  6. 服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。

Dubbo 架構(gòu)具有以下幾個(gè)特點(diǎn)

Dubbo架構(gòu)所擁有的特點(diǎn)分別是連通性、健壯性、伸縮性、以及向未來架構(gòu)的升級(jí)性。

連通性

  • 注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊(cè)中心交互,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較小
  • 監(jiān)控中心負(fù)責(zé)統(tǒng)計(jì)各服務(wù)調(diào)用次數(shù),調(diào)用時(shí)間等,統(tǒng)計(jì)先在內(nèi)存匯總后每分鐘一次發(fā)送到監(jiān)控中心服務(wù)器,并以報(bào)表展示
  • 服務(wù)提供者向注冊(cè)中心注冊(cè)其提供的服務(wù),并匯報(bào)調(diào)用時(shí)間到監(jiān)控中心,此時(shí)間不包含網(wǎng)絡(luò)開銷
  • 服務(wù)消費(fèi)者向注冊(cè)中心獲取服務(wù)提供者地址列表,并根據(jù)負(fù)載算法直接調(diào)用提供者,同時(shí)匯報(bào)調(diào)用時(shí)間到監(jiān)控中心,此時(shí)間包含網(wǎng)絡(luò)開銷
  • 注冊(cè)中心,服務(wù)提供者,服務(wù)消費(fèi)者三者之間均為長連接,監(jiān)控中心除外
  • 注冊(cè)中心通過長連接感知服務(wù)提供者的存在,服務(wù)提供者宕機(jī),注冊(cè)中心將立即推送事件通知消費(fèi)者
  • 注冊(cè)中心和監(jiān)控中心全部宕機(jī),不影響已運(yùn)行的提供者和消費(fèi)者,消費(fèi)者在本地緩存了提供者列表
  • 注冊(cè)中心和監(jiān)控中心都是可選的,服務(wù)消費(fèi)者可以直連服務(wù)提供者

健壯性

  • 監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)
  • 數(shù)據(jù)庫宕掉后,注冊(cè)中心仍能通過緩存提供服務(wù)列表查詢,但不能注冊(cè)新服務(wù)
  • 注冊(cè)中心對(duì)等集群,任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)
  • 注冊(cè)中心全部宕掉后,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過本地緩存通訊
  • 服務(wù)提供者無狀態(tài),任意一臺(tái)宕掉后,不影響使用
  • 服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無法使用,并無限次重連等待服務(wù)提供者恢復(fù)

伸縮性

  • 注冊(cè)中心為對(duì)等集群,可動(dòng)態(tài)增加機(jī)器部署實(shí)例,所有客戶端將自動(dòng)發(fā)現(xiàn)新的注冊(cè)中心
  • 服務(wù)提供者無狀態(tài),可動(dòng)態(tài)增加機(jī)器部署實(shí)例,注冊(cè)中心將推送新的服務(wù)提供者信息給消費(fèi)者

Dubbo 前期準(zhǔn)備

Zookeeper 安裝

  1. zookeeperwindows 安裝

  2. 配置 zookeeper配置文件

    • 打開 conf目錄下將 zoo_sample.cfg 配置文件復(fù)制并重命名為 zoo.cfg 配置文件
    • 修改配置文件
    # AdminServer 占用了 8080 端口,將其改用為9999
    admin.serverPort=9999
    # 這里原來是 Linux 中的路徑顯示,改為 window 路徑并且需要手動(dòng)創(chuàng)建 tmp_data 文件夾
    dataDir=../tmp_data
    
  3. 運(yùn)行 zookeeper服務(wù)器

    • bin目錄下通過命令啟動(dòng) zookeeper服務(wù)
    xxx\zookeeper\apache-zookeeper-3.6.2-bin\apache-zookeeper-3.6.2-bin\bin> zkServer.cmd
    
  4. 運(yùn)行 zookeeper客戶端

    • bin目錄下通過命令啟動(dòng) zookeeper客戶端
    xxx\zookeeper\apache-zookeeper-3.6.2-bin\apache-zookeeper-3.6.2-bin\bin> zkCli.cmd
    
    • 啟動(dòng)后輸入命令顯示如下表示成功
    image

dubbo-admin 安裝

  1. 下載 dubbo-admin

  2. 修改 dubbo-admin-server 配置文件

    • 進(jìn)入 dubbo-admin 的 dubbo-admin-server 目錄中
    cd dubbo-admin/dubbo-admin-server
    
    • 修改 dubbo-admin-server\src\main\resources\application.properties 配置文件
    # centers in dubbo2.7
    admin.registry.address=zookeeper://127.0.0.1:2181
    admin.config-center=zookeeper://127.0.0.1:2181
    admin.metadata-report.address=zookeeper://127.0.0.1:2181
    
  3. 將 dubbo-admin-server 進(jìn)行打包

    • 使用 maven進(jìn)行打包:mvn clean package
  4. 啟動(dòng) dubbo-admin-server

    • 進(jìn)入生成的 target目錄中,運(yùn)行啟動(dòng)后臺(tái)

      java -jar dubboxxx.jar

  5. 啟動(dòng) dubbo-admin-ui

    • 由于 dubbo-admin 是一個(gè)前后端分離的項(xiàng)目,所以還需要啟動(dòng)前端項(xiàng)目

    • 需要提前安裝 node.js 才可以使用 npm 命令來運(yùn)行程序

      > npm install
      > npm run dev
      
  6. http://localhost:8082 中便可查看運(yùn)行界面

    • 默認(rèn)賬戶密碼均為:root

Dubbo 入門案例

使用 XML 啟動(dòng) Dubbo 案例

  1. 項(xiàng)目目錄結(jié)構(gòu)如下

    image
  1. Maven 核心配置文件如下

    <properties>
        <!-- 定義 dubbo 的版本 -->
        <dubbo.version>2.7.8</dubbo.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- 使用 zookeeper 作為注冊(cè)中心-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
        </dependency>
    </dependencies>
    
  2. 在 dubbo-demo-xml-interface 中創(chuàng)建公共接口

    package com.study;
    /**
     * 創(chuàng)建公共接口<p>
     * @author DeadBoty
     * @since 2020/10/23 16:22
     */
    public interface DemoService {
        String sayHello(String name);
    }
    
  3. 在 dubbo-demo-xml-provider 中創(chuàng)建接口實(shí)現(xiàn)類

    • 在 pom.xml 中添加 dubbo-demo-xml-interface 的依賴
    <dependencies>
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>dubbo-demo-xml-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
    • 創(chuàng)建配置文件:provider.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-4.3.xsd
           http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
        <!-- 提供方應(yīng)用信息,用于計(jì)算依賴關(guān)系 -->
        <dubbo:application name="dubbo-demo-hello"  />
    
        <!-- 使用 zookeeper 廣播注冊(cè)中心暴露服務(wù)地址 -->
        <!-- <dubbo:registry address="zookeeper://127.0.0.1:2181" /> -->
        <dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" />
    
        <!-- 用 dubbo 協(xié)議在 20880 端口暴露服務(wù) -->
        <dubbo:protocol name="dubbo" port="20880" />
    
        <!-- 聲明需要暴露的服務(wù)接口 -->
        <dubbo:service interface="com.study.DemoService" ref="demoService" />
    
        <!-- 和本地 bean 一樣實(shí)現(xiàn)服務(wù) -->
        <bean id="demoService" class="com.study.DemoServiceImpl" />
    </beans>
    
    • 編寫接口實(shí)現(xiàn)類
    package com.study;
    /**
     * 公共接口實(shí)現(xiàn)類<p>
     * @author DeadBoty
     * @since 2020/10/23 17:17
     */
    public class DemoServiceImpl implements DemoService {
        @Override
        public String sayHello(String name) {
            return "Hello, " + name;
        }
    }
    
    • 編寫啟動(dòng)方法
    package com.study;
    
    /**
     * 服務(wù)提供方啟動(dòng)<p>
     * @author DeadBoty
     * @since 2020/10/23 17:21
     */
    public class Provider {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("provider.xml");
            applicationContext.start();
            // 輸入一個(gè)字符退出
            System.in.read();
        }
    }
    
    • 在 dubbo-admin 的可視化中可以看到服務(wù)提供方
    image
  4. 在 dubbo-demo-xml-consumer 中實(shí)現(xiàn)服務(wù)的調(diào)用

    • 在 pom.xml 中添加 dubbo-demo-xml-interface 的依賴
    <dependencies>
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>dubbo-demo-xml-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
    • 創(chuàng)建配置文件: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://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">
        
        <!-- 消費(fèi)方應(yīng)用名,用于計(jì)算依賴關(guān)系,不是匹配條件,不要與提供方一樣 -->
        <dubbo:application name="consumer-of-hello-app"  />
        
        <!-- 使用 zookeeper 廣播注冊(cè)中心暴露發(fā)現(xiàn)服務(wù)地址 -->
        <dubbo:registry address="zookeeper://127.0.0.1:2181" />
        
        <!-- 生成遠(yuǎn)程服務(wù)代理,可以和本地 bean 一樣使用 demoService -->
        <dubbo:reference id="demoService" interface="com.study.DemoService" />
        
    </beans>
    
    • 編寫服務(wù)消費(fèi)啟動(dòng)
    package com.study;
    
    /**
     * 服務(wù)消費(fèi)方啟動(dòng)類<p>
     * @author DeadBoty
     * @since 2020/10/23 17:34
     */
    public class Consumer {
        public static void main(String[] args) throws Exception {
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
            DemoService demoService = applicationContext.getBean("demoService", DemoService.class);
            System.out.println(demoService.sayHello("法外狂徒張三"));
        }
    }
    
    • 服務(wù)消費(fèi)與提供方的關(guān)系
image

基于注解開發(fā)

Spring 的注解開發(fā)和 Spring Boot 相似,所以這里直接使用 Spring Boot 進(jìn)行注解的開發(fā)

  1. 項(xiàng)目目錄結(jié)構(gòu)如下

    image
  2. Maven 中各部分的配置

    • dubbo-demo-annotation 的 pom.xml
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <dependencies>
       <!-- Dubbo Spring Boot Starter -->
       <dependency>
          <groupId>org.apache.dubbo</groupId>
          <artifactId>dubbo-spring-boot-starter</artifactId>
          <version>2.7.7</version>
       </dependency>
    
       <!-- dubbo 依賴 -->
       <dependency>
          <groupId>org.apache.dubbo</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.7.7</version>
       </dependency>
    
       <!-- 導(dǎo)入 curator 分布式協(xié)調(diào)服務(wù) -->
       <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.0.1</version>
       </dependency>
    
       <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-recipes</artifactId>
          <version>4.0.1</version>
       </dependency>
    
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
       </dependency>
    
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
          <exclusions>
             <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
             </exclusion>
          </exclusions>
       </dependency>
    </dependencies>
    
    • dubbo-demo-provider 的 pom.xml
    <parent>
        <artifactId>dubbo-demo-annotation</artifactId>
        <groupId>com.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <dependencies>
        <!-- 導(dǎo)入 Spring Web 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>dubbo-demo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
    • dubbo-demo-consumer 的 pom.xml
    <parent>
        <artifactId>dubbo-demo-annotation</artifactId>
        <groupId>com.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <dependencies>
        <!-- 導(dǎo)入 Spring Web 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>com.study</groupId>
            <artifactId>dubbo-demo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    
    </dependencies>
    
  3. 在 dubbo-demo-interface 創(chuàng)建公共接口

    package com.study;
    
    /**
     * 創(chuàng)建公共接口<p>
     * @author DeadBoty
     * @since 2020/10/23 16:22
     */
    public interface DemoService {
        String sayHello(String name);
    }
    
  4. 在 dubbo-demo-provider 中創(chuàng)建接口實(shí)現(xiàn)類

    • dubbo 的配置文件: application.yml
    # 定義端口號(hào)
    server:
      port: 8181
    # 定義 dubbo 相關(guān)配置
    dubbo:
      application:
        name: annotation-demo-provider
      protocol:
        name: dubbo
        port: 20880
      registry:
        protocol: zookeeper
        address: 127.0.0.1:2181
    
    • 接口實(shí)現(xiàn)類
    package com.study.service;
    
    /**
     * 公共接口的具體實(shí)現(xiàn)<p>
     * @author DeadBoty
     * @since 2020/10/25 14:59
     */
    @Service
    // 需要提供的服務(wù)
    @DubboService
    public class DemoServiceImpl implements DemoService {
    
        @Override
        public String sayHello(String name) {
            return "你好~~~ " + name;
        }
    
    }
    
    • 啟動(dòng)類
    package com.study;
    
    /**
     * Spring Boot 啟動(dòng)類<p>
     * @author DeadBoty
     * @since 2020/10/25 14:53
     */
    @SpringBootApplication
    // 啟動(dòng) Dubbo 的注解
    @EnableDubbo
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
  5. 在 dubbo-demo-consumer 中實(shí)現(xiàn)服務(wù)的調(diào)用

    • dubbo 的配置
    server:
      port: 8182
    dubbo:
      application:
        name: annotation-demo-consumer
      registry:
        protocol: zookeeper
        address: 127.0.0.1:2181
    
    • 遠(yuǎn)程調(diào)用服務(wù)
    package com.study.controller;
    
    /**
     * 服務(wù)消費(fèi)調(diào)用<p>
     * @author DeadBoty
     * @since 2020/10/25 14:59
     */
    @RestController
    @RequestMapping("/demo")
    public class DemoController {
        // 使用 @DubboReference 來實(shí)現(xiàn)遠(yuǎn)程方法引用服務(wù)
        @DubboReference
        DemoService demoService;
    
        @GetMapping("/{name}")
        public String sayHello(@PathVariable String name) throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            // 返回了 Json 數(shù)據(jù)
            return mapper.writeValueAsString(demoService.sayHello(name));
        }
    }
    
    • 啟動(dòng)類
    package com.study;
    
    /**
     * 服務(wù)消費(fèi)端啟動(dòng)類<p>
     * @author DeadBoty
     * @since 2020/10/25 14:42
     */
    @SpringBootApplication
    @EnableDubbo
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    
  6. 啟動(dòng)服務(wù)后調(diào)用方法 http://localhost:8182/demo/%E6%B3%95%E5%A4%96%E7%8B%82%E5%BE%92%E5%BC%A0%E4%B8%89

    • 結(jié)果如下:
    image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容