1. 程式人生 > >Dubbo框架原理簡要介紹

Dubbo框架原理簡要介紹


公司為搭建分散式系統學習使用dubbo框架


參考文件: 阿里巴巴Duboo官網

一 、知識點

  1. SOA(Service Oriented Architecture):面向服務的架構。
    • 由 服務治理、服務註冊和發現、RPC、監控中心、排程中心以及服務路由、負載均衡等功能模組組成的資源排程和治理中心。

二、 RPC的演進

RPC框架演變

  • 框架演進:ORM–>MVC–>RPC–>SOA
  • 架構演進:單一應用架構–>垂直應用架構—>分散式服務架構–>流動計算架構
  • 單一應用架構
    • 網站流量小的時候,將所有功能集中到單一應用以減少成本。效能瓶頸在於 ORM框架。
  • 垂直應用架構
    • 網站流量增大,橫向擴充套件帶來的效益越來越低,將應用拆分為互不相干的幾個應用以提升效率。效能瓶頸在於MVC框架。
  • 分散式服務架構
    • 當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。 此時,用於提高業務複用及整合的分散式服務框架(RPC)是關鍵。
  • 彈性計算架構
    • 當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率。 此時,用於提高機器利用率的資源排程和治理中心(SOA)是關鍵。

三、 架構簡介

架構圖
架構圖

節點角色

  1. Provider:服務提供方,在啟動時向註冊中心註冊服務;
  2. Consumer:服務消費方,向註冊中心請求服務提供方列表,在本地做負載均衡呼叫服務;
  3. Register:註冊中心,提供服務註冊與發現(一般由Zookeeper擔當),通過長連線與Provider和Consumer保持連線,負責監控Provider的上下線並及時通知Consumer;
  4. Monitor:監控中心,負責統計服務的效能資料;
  5. Container:服務執行容器。

呼叫關係

  1. “0.start”:服務執行容器啟動、載入、執行服務提供方,一般由Spring容器啟動Jar執行;
  2. “1.register”: 服務提供方在啟動時,向註冊中心註冊自己的IP、服務介面等資訊;
  3. “2.subscribe”: 服務消費方向註冊中心訂閱自己感興趣的服務提供方;
  4. “3.notify”: 註冊中心在服務提供方發生變更時將基於長連線向消費方推送訊息;
  5. “4.invoke”: 服務消費方在本地對服務列表做軟負載均衡演算法,選擇最優的服務提供方進行RPC呼叫;
  6. “5.count”: 消費方和提供方向監控中心 定時非同步推送服務呼叫次數和時間,消費方的包括網路耗時,提供方不包括網路耗時。

效能說明

  1. 連通性:註冊中心通過長連線與Provider和Consumer進行通訊,Provider和Consumer直接通過PRC直接呼叫,其只在啟動時向註冊中心註冊和訂閱,註冊中心不轉發請求,當註冊中心宕機,Consumer依然可以通過本地快取的Provider的地址列表進行呼叫;Provider和Consumer與監控中心定時地通過非同步通訊方式進行服務呼叫資訊上傳;
  2. 健壯性: 服務提供者無狀態,任意一臺宕掉後,不影響使用,服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復。
  3. 伸縮性:註冊中心為對等叢集,可動態增加機器部署例項,所有客戶端將自動發現新的註冊中心,服務提供者無狀態,可動態增加機器部署例項,註冊中心將推送新的服務提供者資訊給消費者。
  4. 擴充套件性:當服務叢集規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行彈性計算,現有分散式服務架構不會帶來阻力。

四、 使用簡介

Dubbo是基於Spring的框架,其配置採用XML和註解的方式,使用Spring的BeanFactory載入Bean,執行在Spring容器中。

服務提供方

  1. 定義服務介面

DemoService.java

package com.alibaba.dubbo.demo;
public interface DemoService {
    String sayHello(String name);
}

打包成Jar包在服務提供方和消費者處使用,該工程裡除了介面定義以外,還有各種實體類和通用工具類

  • 實現服務介面

  • DemoServiceImpl.java

    package com.alibaba.dubbo.demo.provider;
    import com.alibaba.dubbo.demo.DemoService;
    public class DemoServiceImpl implements DemoService {
       public String sayHello(String name) {
           return "Hello " + name;
       }
    }

    公司裡將介面定義和服務實現分為了兩個工程,不便於開發人員使用,建議採用Maven的多專案結構,將介面定義和服務實現定義在同一個父專案下。

  • 暴露服務

    • XML方式
    <beans>
    <!--省略schema--!>
    <!-- 提供方應用資訊,用於計算依賴關係 -->
    <dubbo:application name="hello-world-app"  />
    <!-- 使用multicast廣播註冊中心暴露服務地址 -->
    <dubbo:registry address="multicast://224.5.6.7:1234" />
    <!-- 用dubbo協議在20880埠暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 宣告需要暴露的服務介面 -->
    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />
    <!-- 和本地bean一樣實現服務 -->
    <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
    </beans>
    • 註解方式(推薦)

    FooServiceImpl.java

    import com.alibaba.dubbo.config.annotation.Service;
    @Service(version="1.0.0")
    public class FooServiceImpl implements FooService {
    }

    provider.xml

    <!-- 公共資訊,也可以用dubbo.properties配置 -->
    <dubbo:application name="annotation-provider" />
    <dubbo:registry address="127.0.0.1:4548" />
    <!-- 掃描註解包路徑,多個包用逗號分隔,不填pacakge表示掃描當前ApplicationContext中所有的類-->
    <dubbo:annotation package="com.foo.bar.service" />
  • 啟動

  • public static void main(String[] args) throws Exception {
        //載入xml配置啟動Spring的BeanFactory
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/provider.xml"});
        context.start();
        System.in.read(); // 按任意鍵退出
    }

    服務啟動時,將向註冊中心註冊本服務的IP、介面等資訊

    服務消費方

    1. 引用遠端服務介面

    • xml方式

    consumer.xml

    <!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方一樣 -->
    <dubbo:application name="consumer-of-helloworld-app"  />
    
    <!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
    <dubbo:registry address="multicast://224.5.6.7:1234" />
    
    <!-- 生成遠端服務代理,可以和本地bean一樣使用demoService -->
    <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" />
  • 註解方式(推薦)

  •     @Component
        public class BarAction {
            @Reference(version="1.0.0")
            private FooService fooService;
        }
      
    • 呼叫服務

       public static void main(String[] args) throws Exception {
           ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/consumer.xml"});
           context.start();
           DemoService demoService = (DemoService)context.getBean("demoService"); // 獲取遠端服務代理
      
           String hello = demoService.sayHello("world"); // 執行遠端方法
           System.out.println( hello ); // 顯示呼叫結果
      }