Dubbo從入門到實戰:入門篇


 

很多時候,其實我們使用這個技術的時候,可能都是因為項目需要,所以,我們就用了,但是,至於為什么我們需要用到這個技術,可能自身並不是很了解的,但是,其實了解技術的來由及背景知識,對於理解一項技術還是有幫助的,那么,dubbo是怎么被提上日程的呢?

在互聯網的發展過程中,在以前,我們只需要一個服務器,將程序全部打包好就可以,但是,隨着流量的增大,常規的垂直應用架構已無法應對,所以,架構就發生了演變。

1 單一應用架構

2 應用和數據庫單獨部署

3 應用和數據庫集群部署

4 數據庫壓力變大,讀寫分離

5 使用緩存技術加快速度

6 數據庫分庫分表

7 應用分為不同的類型拆分

發展到這個階段的時候,我們發現,應用與應用之間的關系已經十分的復雜了,就會出現以下幾個問題(以下摘錄於官網):

① 當服務越來越多時,服務 URL 配置管理變得非常困難,F5 硬件負載均衡器的單點壓力也越來越大。

② 當進一步發展,服務間依賴關系變得錯蹤復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。

③ 接着,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什么時候該加機器?

為了解決這由於架構的演變所產生的問題幾個問題,於是,dubbo 產生了。當然,解決這個問題的技術不止 dubbo 。

 

從上面 Dubbo 的服務治理圖我們就可以看到,Duboo 很好了解決了上面所出現的一些問題。

所以,當你的系統架構發展到了這種階段的時候,就需要考慮使用 Dubbo 了。

二 Dubbo 技術架構

我們已經非常清楚的知道為什么在我們的系統中需要 Dubbo 這項技術了,下面,我們接着嘮叨嘮叨 Dubbo 的架構。

首先,上一張圖(摘自官網)。

 

看到圖之后,可能你對上面的幾個概念還是一臉懵逼,無從下手,下面,帶你看看這幾個角色到底是什么意思?

節點角色說明

看了這幾個概念后似乎發現,其實 Dubbo 的架構也是很簡單的(其實現細節是復雜的),為什么這么說呢,有沒有發現,其實很像 生產者-消費者 模型。只是在這種模型上,加上了 注冊中心和監控中心 ,用於管理提供方提供的 url ,以及管理整個過程。

那么,整個發布-訂閱的過程就非常的簡單了。

  • 啟動容器,加載, 運行服務提供者 。
  • 服務提供者在啟動時,在注冊中心 發布注冊 自己提供的 服務 。
  • 服務消費者在啟動時,在注冊中心 訂閱 自己所需的 服務 。

如果考慮 失敗或變更 的情況,就需要考慮下面的過程。

  • 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
  • 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
  • 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。

通過這番講解,我相信 Dubbo 的架構我們也輕車熟路了,那就直接入手,開車吧。

三 Dubbo 開始入門

終於走到這一步了,寫到這里停了大概一周的時間,主要原因還是最近項目太忙,趕着交差呢,今天希望能一鼓作氣,完完整整的寫完 dubbo 的基礎篇!

3.1 服務端

首先,我們先把服務端的接口寫好,因為其實 dubbo 的作用簡單來說就是給消費端提供接口。

接口定義

  /**
   * xml方式服務提供者接口
   */
  public interface ProviderService {

      String SayHello(String word);
  }
 

這個接口非常簡單,只是包含一個 SayHello 的方法。

接着,定義它的實現類。

/**
 * xml方式服務提供者實現類
 */
public class ProviderServiceImpl implements ProviderService{

    public String SayHello(String word) {
        return word;
    }
}

這樣我們就把我們的接口寫好了,那么我們應該怎么將我們的服務暴露出去呢?

導入 maven 依賴

<?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>com.ouyangsihai</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <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>

    </dependencies>
</project>

這里使用的 dubbo 的版本是 2.6.6 ,需要注意的是,如果你只導入 dubbo 的包的時候是 會報錯 的, 找不到 netty 和 curator 的依賴 ,所以,在這里我們需要把這兩個的依賴加上,就不會報錯了。

另外,這里我們使用 zookeeper 作為注冊中心。

到目前為止,dubbo 需要的環境就已經可以了,下面,我們就把上面剛剛定義的接口暴露出去。

暴露接口(xml 配置方法)

首先,我們在我們項目的 resource 目錄下 創建 META-INF.spring 包 ,然后再創建 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" owner="sihai">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="55555"/>
    </dubbo:application>

    <dubbo:monitor protocol="registry"/>

    <!--dubbo這個服務所要暴露的服務地址所對應的注冊中心-->
    <!--<dubbo:registry address="N/A"/>-->
    <dubbo:registry address="N/A" />

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

    <!--服務發布的配置,需要暴露的服務接口-->
    <dubbo:service
            interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService"/>

    <!--Bean bean定義-->
    <bean id="providerService" class="com.sihai.dubbo.provider.service.ProviderServiceImpl"/>

</beans>

① 上面的文件其實就是類似 spring 的配置文件,而且,dubbo 底層就是 spring。

 節點:dubbo:application 就是整個項目在分布式架構中的唯一名稱,可以在 name 屬性中配置,另外還可以配置 owner 字段,表示屬於誰。 下面的參數是可以不配置的,這里配置是因為出現了端口的沖突,所以配置。

 節點:dubbo:monitor 監控中心配置, 用於配置連接監控中心相關信息,可以不配置,不是必須的參數。

 節點:dubbo:registry 配置注冊中心的信息,比如,這里我們可以配置 zookeeper 作為我們的注冊中心。 address 是注冊中心的地址,這里我們配置的是 N/A 表示由 dubbo 自動分配地址。或者說是一種直連的方式,不通過注冊中心。

 節點:dubbo:protocol 服務發布的時候 dubbo 依賴什么協議,可以配置 dubbo、webserovice、Thrift、Hessain、http等協議。

 節點:dubbo:service 這個節點就是我們的重點了,當我們服務發布的時候,我們就是通過這個配置將我們的服務發布出去的。 interface 是接口的包路徑, ref 是第 ⑦ 點配置的接口的 bean。

⑦ 最后,我們需要像配置 spring 的接口一樣,配置接口的 bean。

到這一步,關於服務端的配置就完成了,下面我們通過 main 方法 將接口發布出去。

發布接口

package com.sihai.dubbo.provider;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.container.Main;
import com.sihai.dubbo.provider.service.ProviderService;
import com.sihai.dubbo.provider.service.ProviderServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * xml方式啟動
 *
 */
public class App 
{
    public static void main( String[] args ) throws IOException {
        //加載xml配置文件啟動
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");
        context.start();
        System.in.read(); // 按任意鍵退出
    }
}

發布接口非常簡單,因為 dubbo 底層就是依賴 spring 的,所以,我們只需要通過 ClassPathXmlApplicationContext 拿到我們剛剛配置好的 xml ,然后調用 context.start() 方法就啟動了。

看到下面的截圖,就算是啟動成功了,接口也就發布出去了。

你以為到這里就結束了了,並不是的,我們拿到 dubbo 暴露出去的 url 分析分析。

dubbo 暴露的 url

dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider&timestamp=1562077289380

分析

① 首先,在形式上我們發現,其實這么牛逼的 dubbo 也是用 類似於 http 的協議 發布自己的服務的,只是這里我們用的是 dubbo 協議 。

 dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService 上面這段鏈接就是 ? 之前的鏈接,構成: 協議://ip:端口/接口 。發現是不是也沒有什么神秘的。

 anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider&timestamp=1562077289380 ? 之后的字符串,分析后你發現,這些都是剛剛在 provider.xml 中配置的字段,然后通過 & 拼接而成的,聞到了 http 的香味了嗎?

終於,dubbo 服務端入門了。下面我們看看拿到了 url 后,怎么消費呢?

3.2 消費端

上面提到,我們在服務端提供的只是點對點的方式提供服務,並沒有使用注冊中心,所以,下面的配置也是會有一些不一樣的。

消費端環境配置

首先,我們在消費端的 resource 下建立配置文件 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">

    <!--當前項目在整個分布式架構里面的唯一名稱,計算依賴關系的標簽-->
    <dubbo:application name="consumer" owner="sihai"/>

    <!--dubbo這個服務所要暴露的服務地址所對應的注冊中心-->
    <!--點對點的方式-->
    <dubbo:registry address="N/A" />
    <!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>-->

    <!--生成一個遠程服務的調用代理-->
    <!--點對點方式-->
    <dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"
                     url="dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService"/>

    <!--<dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>-->

</beans>

分析

① 發現這里的 dubbo:application 和 dubbo:registry 是一致的。

 dubbo:reference :我們這里采用 點對點 的方式,所以,需要配置在服務端暴露的 url 。

maven 依賴

和服務端一樣

 

<?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>com.ouyangsihai</groupId>
    <artifactId>dubbo-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.ouyangsihai</groupId>
            <artifactId>dubbo-provider</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>
    </dependencies>
</project>

調用服務

 

package com.sihai.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.sihai.dubbo.provider.service.ProviderService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * xml的方式調用
 *
 */
public class App 
{
    public static void main( String[] args ) throws IOException {

        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");
        context.start();
        ProviderService providerService = (ProviderService) context.getBean("providerService");
        String str = providerService.SayHello("hello");
        System.out.println(str);
        System.in.read();

    }
}

這里和服務端的發布如出一轍。

如此,我們就成功調用接口了。

文章有不當之處,歡迎指正,如果喜歡微信閱讀,你也可以關注我的 微信公眾號 : Java技術zhai ,獲取優質學習資源。

免費Java高級資料需要自己領取,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高並發分布式等教程,一共40G。
傳送門: https://mp.weixin.qq.com/s/DHCu6AkF4nz4hNOv9c0IZg


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM