Dubble 入門

Dubbo 01

架構模型

傳統架構 All in One

測試麻煩,微小修改 全都得從新測html

單體架構也稱之爲單體系統或者是單體應用。就是一種把系統中全部的功能、模塊耦合在一個應用中的架構方式。其優勢爲:項目易於管理、部署簡單。缺點:測試成本高、可伸縮性差、可靠性差、迭代困難、跨語言程度差、團隊協做難java

聚合項目劃分linux

單項目容易 由於某個功能致使總體oomredis

拆分完 咋實現spring

SOA 架構: Service-Oriented Architecture

面向服務的架構(SOA)是一個組件模型,它將應用程序拆分紅不一樣功能單元(稱爲服務)經過這些服務之間定義良好的接口和契約聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬件平臺、操做系統和編程語言。這使得構建在各類各樣的系統中的服務能夠以一種統一和通用的方式進行交互。數據庫

在沒有實施SOA的年代,從咱們研發的角度來看,只能在代碼級別複用,即Ctrl +V。SOA出現,咱們開始走向了模塊、業務線的複用。apache

SOA年代的典型實現: SOAP協議,CXF框架,XML傳輸編程

xsd,數據校驗json

SOA架構伴隨着軟件研發行業20年的發展,在最初的時候,大型it公司內部系統規模愈來愈大,IT系統愈來愈複雜,All in One單體架構的思想致使公司內項目業務和數據相互隔離,造成了孤島。api

最初,咱們使用數據庫做爲項目之間數據交互和中轉的平臺,如今咱們有了消息中間件。

最初,咱們使用XML完成系統之間解耦與相互關聯,如今咱們有了RPC,Restful

最初,咱們使用業務維度劃分總體項目結構,

最初,咱們多項目節點維護一個共享數據中心,如今咱們作冗餘存儲,閉環數據,保證高效運行及數據最終一致性

最初,SOA思想指導指導咱們把全部的IT系統彙總成一個大的總體,按照業務維度劃分服務,集中化管理 如今咱們拆分抽象服務使其能夠多系統複用相同的功能模塊。

基於dubbo RPC的微服務式架構

RPC遠程過程調用 : Remote Procedure Call Protocol

遠程過程調用協議,它是一種經過網絡從遠程計算機程序上請求服務,而不須要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通訊程序之間攜帶信息數據。在OSI網絡通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。

原來的RPC也有其餘幾種好比DCOM,CORBA,RMI(Java)等

  • RMI——Remote Method Invoke:調用遠程的方法。「方法」通常是附屬於某個對象上的,因此一般RMI指對在遠程的計算機上的某個對象,進行其方法函數的調用。
  • RPC——Remote Procedure Call:遠程過程調用。指的是對網絡上另一個計算機上的,某段特定的函數代碼的調用。

RMI 構建圖

傳輸協議

  • RPC,能夠基於TCP協議,也能夠基於HTTP協議
  • HTTP,基於HTTP協議

傳輸效率

  • RPC,使用自定義的TCP協議,可讓請求報文體積更小,或者使用HTTP2協議,也能夠很好的減小報文的體積,提升傳輸效率
  • HTTP,若是是基於HTTP1.1的協議,請求中會包含不少無用的內容,若是是基於HTTP2.0,那麼簡單的封裝如下是能夠做爲一個RPC來使用的,這時標準RPC框架更多的是服務治理

性能消耗

  • RPC,能夠基於thrift實現高效的二進制傳輸
  • HTTP,大部分是經過json來實現的,字節大小和序列化耗時都比thrift要更消耗性能

負載均衡

  • RPC,基本都自帶了負載均衡策略
  • HTTP,須要配置Nginx,HAProxy來實現

服務治理

  • RPC,能作到自動通知,不影響上游
  • HTTP,須要事先通知,修改Nginx/HAProxy配置

RPC主要用於公司內部的服務調用,性能消耗低,傳輸效率高,服務治理方便。HTTP主要用於對外的異構環境,瀏覽器接口調用,APP接口調用,第三方接口調用等。

概念

Dubbo介紹

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

Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可經過高性能的 RPC 實現服務的輸出和輸入功能,能夠和Spring框架無縫集成。Dubbo框架,是基於容器運行的.。容器是Spring。

官方網站 : http://dubbo.apache.org/

阿里巴巴已經將dubbo框架捐獻給了Apache軟件基金會

Dubbo框架結構

角色

registry

註冊中心. 是用於發佈和訂閱服務的一個平臺.用於替代SOA結構體系框架中的ESB服務總線的。

發佈

開發服務端代碼完畢後, 將服務信息發佈出去. 實現一個服務的公開.

訂閱

客戶端程序,從註冊中心下載服務內容 這個過程是訂閱.

訂閱服務的時候, 會將發佈的服務全部信息,一次性下載到客戶端.

客戶端也能夠自定義, 修改部分服務配置信息. 如: 超時的時長, 調用的重試次數等.

consumer

服務的消費者, 就是服務的客戶端.

消費者必須使用Dubbo技術開發部分代碼. 基本上都是配置文件定義.

provider

服務的提供者, 就是服務端.

服務端必須使用Dubbo技術開發部分代碼. 以配置文件爲主.

container

容器. Dubbo技術的服務端(Provider), 在啓動執行的時候, 必須依賴容器才能正常啓動.

默認依賴的就是spring容器. 且Dubbo技術不能脫離spring框架.

在2.5.3版本的dubbo中, 默認依賴的是spring2.5版本技術. 能夠選用spring4.5如下版本.

在2.5.7版本的dubbo中, 默認依賴的是spring4.3.10版本技術. 能夠選擇任意的spring版本.

monitor dubbo admin

監控中心. 是Dubbo提供的一個jar工程.

主要功能是監控服務端(Provider)和消費端(Consumer)的使用數據的. 如: 服務端是什麼,有多少接口,多少方法, 調用次數, 壓力信息等. 客戶端有多少, 調用過哪些服務端, 調用了多少次等.

執行流程

  • start: 啓動Spring容器時,自動啓動Dubbo的Provider
  • register: Dubbo的Provider在啓動後自動會去註冊中心註冊內容.註冊的內容包括:
    • Provider的 IP
    • Provider 的端口.
    • Provider 對外提供的接口列表.哪些方法.哪些接口類
    • Dubbo 的版本.
    • 訪問Provider的協議.
  • subscribe: 訂閱.當Consumer啓動時,自動去Registry獲取到所已註冊的服務的信息.
  • notify: 通知.當Provider的信息發生變化時, 自動由Registry向Consumer推送通知.
  • invoke: 調用. Consumer 調用Provider中方法
    • 同步請求.消耗必定性能.可是必須是同步請求,由於須要接收調用方法後的結果.
  • count:次數. 每隔2分鐘,provoider和consumer自動向Monitor發送訪問次數.Monitor進行統計.

協議

Dubbo協議(官方推薦協議)

優勢:

採用NIO複用單一長鏈接,並使用線程池併發處理請求,減小握手和加大併發效率,性能較好(推薦使用)

缺點:

大文件上傳時,可能出現問題(不使用Dubbo文件上傳)

RMI(Remote Method Invocation)協議

優勢:

JDK自帶的能力。可與原生RMI互操做,基於TCP協議

缺點:

偶爾鏈接失敗.

Hessian協議

優勢:

可與原生Hessian互操做,基於HTTP協議

缺點:

需hessian.jar支持,http短鏈接的開銷大

註冊中心

Zookeeper(官方推薦)

優勢:

支持分佈式.不少周邊產品.

缺點:

受限於Zookeeper軟件的穩定性.Zookeeper專門分佈式輔助軟件,穩定較優

Multicast

優勢:

去中心化,不須要單獨安裝軟件.

缺點:

2.2.1 Provider和Consumer和Registry不能跨機房(路由)

Redis

優勢:

支持集羣,性能高

缺點:

要求服務器時間同步.不然可能出現集羣失敗問題.

Simple

優勢:

標準RPC服務.沒有兼容問題

缺點:

不支持集羣.

組件選型及成熟度

http://dubbo.apache.org/zh-cn/docs/user/maturity.html

功能成熟度

Feature Maturity Strength Problem Advise User
併發控制 Tested 併發控制 試用
鏈接控制 Tested 鏈接數控制 試用
直連提供者 Tested 點對點直連服務提供方,用於測試 測試環境使用 Alibaba
分組聚合 Tested 分組聚合返回值,用於菜單聚合等服務 特殊場景使用 可用於生產環境
參數驗證 Tested 參數驗證,JSR303驗證框架集成 對性能有影響 試用 LaiWang
結果緩存 Tested 結果緩存,用於加速請求 試用
泛化引用 Stable 泛化調用,無需業務接口類進行遠程調用,用於測試平臺,開放網關橋接等 可用於生產環境 Alibaba
泛化實現 Stable 泛化實現,無需業務接口類實現任意接口,用於Mock平臺 可用於生產環境 Alibaba
回聲測試 Tested 回聲測試 試用
隱式傳參 Stable 附加參數 可用於生產環境
異步調用 Tested 不可靠異步調用 試用
本地調用 Tested 本地調用 試用
參數回調 Tested 參數回調 特殊場景使用 試用 Registry
事件通知 Tested 事件通知,在遠程調用執行先後觸發 試用
本地存根 Stable 在客戶端執行部分邏輯 可用於生產環境 Alibaba
本地假裝 Stable 僞造返回結果,可在失敗時執行,或直接執行,用於服務降級 需註冊中心支持 可用於生產環境 Alibaba
延遲暴露 Stable 延遲暴露服務,用於等待應用加載warmup數據,或等待spring加載完成 可用於生產環境 Alibaba
延遲鏈接 Tested 延遲創建鏈接,調用時創建 試用 Registry
粘滯鏈接 Tested 粘滯鏈接,老是向同一個提供方發起請求,除非此提供方掛掉,再切換到另外一臺 試用 Registry
令牌驗證 Tested 令牌驗證,用於服務受權 需註冊中心支持 試用
路由規則 Tested 動態決定調用關係 需註冊中心支持 試用
配置規則 Tested 動態下發配置,實現功能的開關 需註冊中心支持 試用
訪問日誌 Tested 訪問日誌,用於記錄調用信息 本地存儲,影響性能,受磁盤大小限制 試用
分佈式事務 Research JTA/XA三階段提交事務 不穩定 不可用

策略成熟度

Feature Maturity Strength Problem Advise User
Zookeeper註冊中心 Stable 支持基於網絡的集羣方式,有普遍周邊開源產品,建議使用dubbo-2.3.3以上版本(推薦使用) 依賴於Zookeeper的穩定性 可用於生產環境
Redis註冊中心 Stable 支持基於客戶端雙寫的集羣方式,性能高 要求服務器時間同步,用於檢查心跳過時髒數據 可用於生產環境
Multicast註冊中心 Tested 去中心化,不須要安裝註冊中心 依賴於網絡拓撲和路由,跨機房有風險 小規模應用或開發測試環境
Simple註冊中心 Tested Dogfooding,註冊中心自己也是一個標準的RPC服務 沒有集羣支持,可能單點故障 試用
Feature Maturity Strength Problem Advise User
Simple監控中心 Stable 支持JFreeChart統計報表 沒有集羣支持,可能單點故障,但故障後不影響RPC運行 可用於生產環境
Feature Maturity Strength Problem Advise User
Dubbo協議 Stable 採用NIO複用單一長鏈接,並使用線程池併發處理請求,減小握手和加大併發效率,性能較好(推薦使用) 在大文件傳輸時,單一鏈接會成爲瓶頸 可用於生產環境 Alibaba
Rmi協議 Stable 可與原生RMI互操做,基於TCP協議 偶爾會鏈接失敗,需重建Stub 可用於生產環境 Alibaba
Hessian協議 Stable 可與原生Hessian互操做,基於HTTP協議 需hessian.jar支持,http短鏈接的開銷大 可用於生產環境
Feature Maturity Strength Problem Advise User
Netty Transporter Stable JBoss的NIO框架,性能較好(推薦使用) 一次請求派發兩種事件,需屏蔽無用事件 可用於生產環境 Alibaba
Mina Transporter Stable 老牌NIO框架,穩定 待發送消息隊列派發不及時,大壓力下,會出現FullGC 可用於生產環境 Alibaba
Grizzly Transporter Tested Sun的NIO框架,應用於GlassFish服務器中 線程池不可擴展,Filter不能攔截下一Filter 試用
Feature Maturity Strength Problem Advise User
Hessian Serialization Stable 性能較好,多語言支持(推薦使用) Hessian的各版本兼容性很差,可能和應用使用的Hessian衝突,Dubbo內嵌了hessian3.2.1的源碼 可用於生產環境 Alibaba
Dubbo Serialization Tested 經過不傳送POJO的類元信息,在大量POJO傳輸時,性能較好 當參數對象增長字段時,需外部文件聲明 試用
Json Serialization Tested 純文本,可跨語言解析,缺省採用FastJson解析 性能較差 試用
Java Serialization Stable Java原生支持 性能較差 可用於生產環境
Feature Maturity Strength Problem Advise User
Javassist ProxyFactory Stable 經過字節碼生成代替反射,性能比較好(推薦使用) 依賴於javassist.jar包,佔用JVM的Perm內存,Perm可能要設大一些:java -XX:PermSize=128m 可用於生產環境 Alibaba
Jdk ProxyFactory Stable JDK原生支持 性能較差 可用於生產環境
Feature Maturity Strength Problem Advise User
Failover Cluster Stable 失敗自動切換,當出現失敗,重試其它服務器,一般用於讀操做(推薦使用) 重試會帶來更長延遲 可用於生產環境 Alibaba
Failfast Cluster Stable 快速失敗,只發起一次調用,失敗當即報錯,一般用於非冪等性的寫操做 若是有機器正在重啓,可能會出現調用失敗 可用於生產環境 Alibaba
Failsafe Cluster Stable 失敗安全,出現異常時,直接忽略,一般用於寫入審計日誌等操做 調用信息丟失 可用於生產環境 Monitor
Failback Cluster Tested 失敗自動恢復,後臺記錄失敗請求,定時重發,一般用於消息通知操做 不可靠,重啓丟失 可用於生產環境 Registry
Forking Cluster Tested 並行調用多個服務器,只要一個成功即返回,一般用於實時性要求較高的讀操做 須要浪費更多服務資源 可用於生產環境
Broadcast Cluster Tested 廣播調用全部提供者,逐個調用,任意一臺報錯則報錯,一般用於更新提供方本地狀態 速度慢,任意一臺報錯則報錯 可用於生產環境
Feature Maturity Strength Problem Advise User
Random LoadBalance Stable 隨機,按權重設置隨機機率(推薦使用) 在一個截面上碰撞的機率高,重試時,可能出現瞬間壓力不均 可用於生產環境 Alibaba
RoundRobin LoadBalance Stable 輪詢,按公約後的權重設置輪詢比率 存在慢的機器累積請求問題,極端狀況可能產生雪崩 可用於生產環境
LeastActive LoadBalance Stable 最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差,使慢的機器收到更少請求 不支持權重,在容量規劃時,不能經過權重把壓力導向一臺機器壓測容量 可用於生產環境
ConsistentHash LoadBalance Stable 一致性Hash,相同參數的請求老是發到同一提供者,當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更 壓力分攤不均 可用於生產環境
Feature Maturity Strength Problem Advise User
條件路由規則 Stable 基於條件表達式的路由規則,功能簡單易用 有些複雜多分支條件狀況,規則很難描述 可用於生產環境 Alibaba
腳本路由規則 Tested 基於腳本引擎的路由規則,功能強大 沒有運行沙箱,腳本能力過於強大,可能成爲後門 試用
Feature Maturity Strength Problem Advise User
Spring Container Stable 自動加載META-INF/spring目錄下的全部Spring配置 可用於生產環境 Alibaba
Jetty Container Stable 啓動一個內嵌Jetty,用於彙報狀態 大量訪問頁面時,會影響服務器的線程和內存 可用於生產環境 Alibaba
Log4j Container Stable 自動配置log4j的配置,在多進程啓動時,自動給日誌文件按進程分目錄 用戶不能控制log4j的配置,不靈活 可用於生產環境 Alibaba

zookeeper安裝

1565092109186

安裝jdk

  • rpm -ivh jdk-8u131-linux-x64.rpm
  • java –version 檢查是否成功

安裝Zookeeper

下載 http://zookeeper.apache.org/ 並上傳解壓縮

配置zookeeper環境變量

修改文件 vi /etc/profile 追加內容

在path後追加/usr/local/zookeeper/bin

注意中間間隔是: 冒號

export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin:/usr/local/zo

okeeper/bin

source /etc/profile 從新加載配置

修改zoo.cfg

重命名zoo_sample.cfg 爲zoo.cfg

默認加載配置文件會找zoo.cfg這個文件

修改配置文件

vi /usr/local/zookeeper/conf/zoo.cfg

建立數據存放目錄

Mkdir /data/zookeeper

建立Myid文件,並寫入服務器編號

1565092323114

注意:這裏寫入myid文件的編號和接下來要配置的服務器列表編號一一對應,每臺服務器配置的編號也應該不同。

Myid文件裏只有一個數字 1

建立好的這個目錄用於存儲zookeeper產生的數據

修改datadir爲剛纔咱們建立的目錄

dataDir=/data/zookeeper

1565092366744

在最後面加入集羣服務器列表

server.1=192.168.2.51:2888:3888

server.2=cm02:2888:3888

server.3=cm03:2888:3888

配置的服務器集羣個數建議是奇數的

半數以上節點存活,就能夠對外提供服務

其中 server.x 這裏的數字編號 就是咱們的myid裏寫入的數字

Cm01是主機名或ip地址

接下來是對外通信端口和內部選舉端口

啓動

zkServer.sh start 命令啓動一臺zookeeper服務器

沒報錯的話 使用jps看一下進程

1565092454496

QuorumPeerMain是zookeeper的主進程

經過status命令能夠查看服務器運行狀態

1565092410017

注意:當咱們使用集羣模式啓動zookeeper的時候,因爲咱們只啓動了一臺服務器,集羣總共3臺,沒有知足zookeeper半數以上節點運行原則,因此服務雖然起來了,可是沒有辦法對外提供服務。

這時咱們須要啓動第二臺服務器

Dubbo Hello World

環境

SpringBoot + dubbo

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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.littlepage</groupId>
    <artifactId>dubbo01</artifactId>
    <version>0.0.1</version>
    <name>dubbo01</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
        <dubbo.version>2.7.1</dubbo.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Apache Dubbo  -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <dependencies>

        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </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>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.2.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.14</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

服務提供方 provider

配置文件

server.port=8081

spring.application.name=DemoProvider
dubbo.scan.base-packages=com.msb.db1.service

dubbo.protocol.name=dubbo
dubbo.protocol.port=666
dubbo.protocol.host=192.168.101.106

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

服務接口

public interface DemoService {
    String sayHello(String name);
}

接口實現

import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

@Service(version = "1.0.0" ,timeout = 10000, interfaceClass = DemoService.class)
@Component
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        // TODO Auto-generated method stub
        System.out.println("來啦~~~!");
        return "hello:" + name;
    }
}

服務消費方 customer

配置

spring.application.name=DemoCustomer
dubbo.scan.base-packages=com.msb.db1.service

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

自動注入

@Reference(version = "1.0.0")
    DemoService serv;

接口

public interface DemoService {

    String sayHello(String name);

}

本地存根(Stub)

服務端的骨架對象(Skeleton)

相關文章
相關標籤/搜索