Dubbo+Zookeeper的簡單入門案例


1.1  Dubbo簡介

Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司開源的一個高性能、輕量級的開源Java RPC框架,可以和Spring框架無縫集成。

什么是RPC

RPC全稱為remote procedure call,即遠程過程調用。比如兩台服務器A和B,A服務器上部署一個應用,B服務器上部署一個應用,A服務器上的應用想調用B服務器上的應用提供的方法,由於兩個應用不在一個內存空間,不能直接調用,所以需要通過網絡來表達調用的語義和傳達調用的數據。

需要注意的是RPC並不是一個具體的技術,而是指整個網絡遠程調用過程。

RPC是一個泛化的概念,嚴格來說一切遠程過程調用手段都屬於RPC范疇。各種開發語言都有自己的RPC框架。Java中的RPC框架比較多,廣泛使用的有RMI、Hessian、Dubbo等。

Dubbo官網地址:http://dubbo.apache.org

Dubbo提供了三大核心能力:面向接口的遠程方法調用智能容錯和負載均衡,以及服務自動注冊和發現

1.1   Dubbo架構

架構

dubbo-architucture

節點角色說明
節點 角色說明
Provider 暴露服務的服務提供方
Consumer 調用遠程服務的服務消費方
Registry 服務注冊與發現的注冊中心
Monitor 統計服務的調用次數和調用時間的監控中心
Container 服務運行容器
調用關系說明
  1. 服務容器負責啟動,加載,運行服務提供者。
  2. 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
  3. 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
  4. 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者。
  5. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
  6. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心。

Dubbo 架構具有以下幾個特點,分別是連通性、健壯性、伸縮性、以及向未來架構的升級性。

連通性

  • 注冊中心負責服務地址的注冊與查找,相當於目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小
  • 監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鍾一次發送到監控中心服務器,並以報表展示
  • 服務提供者向注冊中心注冊其提供的服務,並匯報調用時間到監控中心,此時間不包含網絡開銷
  • 服務消費者向注冊中心獲取服務提供者地址列表,並根據負載算法直接調用提供者,同時匯報調用時間到監控中心,此時間包含網絡開銷
  • 注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外
  • 注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者
  • 注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表
  • 注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者

健壯性

  • 監控中心宕掉不影響使用,只是丟失部分采樣數據
  • 數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務
  • 注冊中心對等集群,任意一台宕掉后,將自動切換到另一台
  • 注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊
  • 服務提供者無狀態,任意一台宕掉后,不影響使用
  • 服務提供者全部宕掉后,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復

伸縮性

  • 注冊中心為對等集群,可動態增加機器部署實例,所有客戶端將自動發現新的注冊中心
  • 服務提供者無狀態,可動態增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者

升級性

當服務集群規模進一步擴大,帶動IT治理結構進一步升級,需要實現動態部署,進行流動計算,現有分布式服務架構不會帶來阻力。下圖是未來可能的一種架構:

dubbo-architucture-futures

節點角色說明
節點 角色說明
Deployer 自動部署服務的本地代理
Repository 倉庫用於存儲服務應用發布包
Scheduler 調度中心基於訪問壓力自動增減服務提供者
Admin 統一管理控制台
Registry 服務注冊與發現的注冊中心
Monitor 統計服務的調用次數和調用時間的監控中心

服務注冊中心Zookeeper

2.1  Zookeeper簡介

2.1.1 Zookeeper簡介

Zookeeper 是 Apache Hadoop 的子項目,是一個樹型的目錄服務,支持變更推送,適合作為 Dubbo 服務的注冊中心,工業強度較高,可用於生產環境,並推薦使用 。

為了便於理解Zookeeper的樹型目錄服務,我們先來看一下我們電腦的文件系統(也是一個樹型目錄結構):

Zookeeper樹型目錄服務:

流程說明:

服務提供者(Provider)啟動時: 向 /dubbo/com.foo.BarService/providers 目錄下寫入自己的 URL 地址

服務消費者(Consumer)啟動時: 訂閱 /dubbo/com.foo.BarService/providers 目錄下的提供者 URL 地址。並向 /dubbo/com.foo.BarService/consumers 目錄下寫入自己的 URL 地址

監控中心(Monitor)啟動時: 訂閱 /dubbo/com.foo.BarService 目錄下的所有提供者和消費者 URL 地址

2.1.2       Zookeeper安裝與啟動

使用資料中提供的windows版本zookeeper服務器進行安裝即可

進入安裝路徑的bin目錄,雙擊zkServer.cmd即可啟動zookeeper服務

簡單案例

Dubbo作為一個RPC框架,其最核心的功能就是要實現跨網絡的遠程調用。現在要創建兩個應用,一個作為服務的提供者,一個作為服務的消費者。通過Dubbo來實現服務消費者遠程調用服務提供者的方法。

項目目錄結構如圖

 

服務提供者

創建一個空工程,並創建maven工程(打包方式為war)dubbodemo_provider模塊,在pom.xml文件中導入如下坐標

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- dubbo相關 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.7</version>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
</dependencies>

 第二步、編寫spring與dubbo整合的服務提供者spring配置文件applicationContext-dubboprovider.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:aop="http://www.springframework.org/schema/aop"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--給當前服務提供者命名-->
    <dubbo:application name="dubbodemo_provider"/>
    <!--指定zookeeper注冊中心的address和port,如果使用的是redis則address使用redis的address-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" ></dubbo:registry>
    <!--協議必須使用dubbo,端口號是提供一個可供消費者使用的端口-->
    <dubbo:protocol name="dubbo" port="20881"/>
    <!--開啟注解掃描,使dubbo的注解生效-->
    <dubbo:annotation package="com.alibaba.provider"/>
    
</beans>

第三步、在web.xml中配置項目加載監聽器,並指定spring配置文件的路徑

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

  <!-- 監聽器監聽其他的spring配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

第四步、編寫service的接口和實現類

Service接口代碼

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

 Service實現類代碼

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.service.provider.HelloService;
//此注解使用的阿里巴巴的dubbo注解
@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public String sayHello(String name) {
        return "hello@@"+name;
    }
}

 服務消費者

第一步、導入坐標

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- dubbo相關 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.7</version>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
</dependencies>

第二步、配置服務消費者的Spring配置文件applicationContext-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:aop="http://www.springframework.org/schema/aop"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--開啟包掃描,用來掃描所有的Spring注解-->
    <context:component-scan base-package="com.alibaba.web.controller.consumer"/>
    <!--開啟MVC注解,使所有的MVC注解生效-->
    <mvc:annotation-driven/>
    <!--為服務消費者在向注冊中心訂閱服務時起個名字-->
    <dubbo:application name="dubbodemo_consumer"/>
    <!--連接到zookeeper注冊中心-->
    <dubbo:registry address="zookeeper://127.0.0.1" port="2181"/>
    <!--開啟包掃描,使dubbo的注解生效,讓當前的被注解的類交給dubbo管理-->
    <dubbo:annotation package="com.alibaba.web.controller.consumer"/>
</beans>

 第三步、在web.xml配置前端控制器,加載spring的配置信息

<servlet>
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext-*.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>

 第四步、編寫控制器

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.provider.HelloService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
    //此處使用阿里巴巴的注解進行注入
    @Reference
    HelloService helloService;

    @RequestMapping("/hello")
    public void hello(String name) {

        String result = helloService.sayHello(name);
        System.out.println(result);
    }
}

 注意:服務提供者的接口必須存在於服務消費者的目錄中,並且該接口的路徑與服務提供者的路徑必須保持一致,一模一樣。

Dubbo相關配置說明

包掃描

服務提供者和服務消費者都需要配置,表示包掃描,作用是掃描指定包(包括子包)下的類

<dubbo:annotation package="cn.itcast.service" />

 

如果不使用包掃描,也可以通過如下配置的方式來發布服務

<bean id="helloService" class="cn.itcast.service.impl.HelloServiceImpl" />
<dubbo:service interface="cn.itcast.HelloService" ref="helloService" />

 

作為服務消費者,可以通過如下配置來引用服務

<!-- 生成遠程服務代理,可以和本地bean一樣使用helloService -->
<dubbo:reference id="helloService" interface="cn.itcast.HelloService" />

 

上面這種方式發布和引用服務,一個配置項(dubbo:servicedubbo:reference)只能發布或者引用一個服務,如果有多個服務,這種方式就比較繁瑣了。推薦使用包掃描方式。

協議

<dubbo:protocol name="dubbo" port="20880"/>

 

一般在服務提供者一方配置,可以指定使用的協議名稱和端口號。

其中Dubbo支持的協議有:dubbo、rmi、hessian、http、webservice、rest、redis等。

推薦使用的是dubbo協議

dubbo 協議采用單一長連接和 NIO 異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。

也可以在同一個工程中配置多個協議,不同服務可以使用不同的協議

 啟動時檢查

<dubbo:consumer check="false"/>

 

上面這個配置需要配置在服務消費者一方,如果不配置默認check值為true。Dubbo 缺省會在啟動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題。可以通過將check值改為false來關閉檢查。

建議在開發階段將check值設置為false,在生產環境下改為true。

Dubbo管理控制台

我們在開發時,需要知道Zookeeper注冊中心都注冊了哪些服務,有哪些消費者來消費這些服務。我們可以通過部署一個管理中心來實現。其實管理中心就是一個web應用,部署到tomcat即可

安裝

安裝步驟:

(1)將資料中的dubbo-admin-2.6.0.war文件復制到tomcat的webapps目錄下

(2)啟動tomcat,此war文件會自動解壓

(3)修改WEB-INF下的dubbo.properties文件,注意dubbo.registry.address對應的值需要對應當前使用的Zookeeper的ip地址和端口號

dubbo.registry.address=zookeeper://Ip:2181 ​

dubbo.admin.root.password=root ​

dubbo.admin.guest.password=guest

 

(4)重啟tomcat

使用

操作步驟:

訪問http://localhost:8080/dubbo-admin-2.6.0/,輸入用戶名(root)和密碼(root)

 


免責聲明!

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



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