Spring Boot 中使用 Dubbo 詳解

Dubbo是阿里巴巴SOA服務化治理方案的核心框架,天天爲2,000+個服務提供3,000,000,000+次訪問量支持,並被普遍應用於阿里巴巴集團的各成員站點。Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。php

Dubbo 簡介

Dubbo 是什麼?

Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,若是沒有分佈式的需求,實際上是不須要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求,而且本質上是個服務調用的東東,說白了就是個遠程服務調用的分佈式框架java

其核心部分包含:git

1.遠程通信: 提供對多種基於長鏈接的NIO框架抽象封裝,包括多種線程模型,序列化,以及「請求-響應」模式的信息交換方式。
2.集羣容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持。
3.自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方能夠平滑增長或減小機器。github

Dubbo 能作什麼?

1.透明化的遠程方法調用,就像調用本地方法同樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,下降成本,減小單點。
3.服務自動註冊與發現,再也不須要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,而且可以平滑添加或刪除服務提供者。算法

Dubbo 的架構

架構圖

節點角色說明spring

節點 角色說明
Provider 暴露服務的服務提供方
Consumer 調用遠程服務的服務消費方
Registry 服務註冊與發現的註冊中心
Monitor 統計服務的調用次調和調用時間的監控中心
Container 服務運行容器

Dubbo提供三個關鍵功能,包括基於接口的遠程呼叫,容錯和負載平衡以及自動服務註冊和發現數據庫

調用關係說明segmentfault

1.服務容器負責啓動,加載,運行服務提供者。
2.服務提供者在啓動時,向註冊中心註冊本身提供的服務。
3.服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
4.註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
5.服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
6.服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。api

Dubbo 特色

Dubbo 架構具備如下幾個特色,分別是連通性、健壯性、伸縮性、以及向將來架構的升級性緩存

連通性

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

健狀性

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

伸縮性

  • 註冊中心爲對等集羣,可動態增長機器部署實例,全部客戶端將自動發現新的註冊中心
  • 服務提供者無狀態,可動態增長機器部署實例,註冊中心將推送新的服務提供者信息給消費者

升級性

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

將來可能的一種架構

節點角色說明

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

快速開始

Dubbo 採用全 Spring 配置方式,透明化接入應用,對應用沒有任何 API 侵入,只需用 Spring 加載 Dubbo 的配置便可,Dubbo 基於 Spring 的 Schema 擴展進行加載。

環境安裝

任選其一

CentOs7.3 搭建 ZooKeeper-3.4.9 單機服務
CentOs7.3 搭建 ZooKeeper-3.4.9 Cluster 集羣服務

Github 代碼

代碼我已放到 Github ,導入spring-boot-dubbo 項目

github github.com/souyunku/sp…

Maven依賴

在項目中添加 dubbo 依賴

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.6</version>
</dependency>
複製代碼

定義服務接口

項目:dubbo-api

public interface DemoService {
    String sayHello(String name);
}
複製代碼

服務提供方

項目:dubbo-provider,在服務提供方實現接口

@Service("demoService")
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress();
    }
}
複製代碼

加載 dubbo 配置

@Configuration
@PropertySource("classpath:dubbo.properties")
@ImportResource({"classpath:dubbo/*.xml"})
public class PropertiesConfig {
}
複製代碼

在提供方增長暴露服務配置 : <dubbo:service>

dubbo-provider.xml

<!-- 聲明須要暴露的服務接口 -->
<dubbo:service interface="io.ymq.dubbo.api.DemoService" ref="demoService"/>
複製代碼

服務消費方

項目:dubbo-consumer ,消費消費遠程方法

@Service("consumerDemoService")
public class ConsumerDemoService {

    @Autowired
    private DemoService demoService;

    public void sayHello(String name) {
        String hello = demoService.sayHello(name); // 執行消費遠程方法
        System.out.println(hello); // 顯示調用結果
    }
	
}
複製代碼

加載 dubbo 配置

@Configuration
@PropertySource("classpath:dubbo.properties")
@ImportResource({"classpath:dubbo/*.xml"})
public class PropertiesConfig {
}
複製代碼

在消費方增長引用服務配置: <dubbo:reference>

dubbo-consumer.xml

<!-- 增長引用遠程服務配置 能夠和本地bean同樣使用demoService -->
<dubbo:reference id="demoService" check="false" interface="io.ymq.dubbo.api.DemoService"/>
複製代碼

遠程服務 Dubbo 配置

項目:dubbo-provider ,dubbo-consumer 同樣配置

dubbo.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="${spring.application.name}" />

    <!-- 使用multicast廣播註冊中心暴露服務地址 -->
    <dubbo:registry protocol="zookeeper" address="${zookeeper.connect}" file="${dubbo.cache}"/>

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="${dubbo.protocol.port}" threadpool="${dubbo.protocol.threadpool}" threads="${dubbo.protocol.threads}"/>

    <!-- 提供方的缺省值,當ProtocolConfig和ServiceConfig某屬性沒有配置時,採用此缺省值,可選。-->
    <dubbo:provider connections="${dubbo.provider.connections}" timeout="${dubbo.provider.timeout}" retries="${dubbo.provider.retries}" version="${dubbo.provider.version}" />

    <!-- 消費方缺省配置,當ReferenceConfig某屬性沒有配置時,採用此缺省值,可選。-->
    <dubbo:consumer version="${dubbo.provider.version}" />

    <!-- 監控中心配置,用於配置鏈接監控中心相關信息,可選。-->
    <dubbo:monitor protocol="registry"/>

</beans>
複製代碼

dubbo.properties

#########################################################
# dubbo config
#暴露服務端口
dubbo.protocol.port=20880
#提供方超時時間
dubbo.provider.timeout=10000
#提供方版本
dubbo.provider.version=1.0
#表示該服務使用獨的五條條長連
dubbo.provider.connections=5
# 固定大小線程池,啓動時創建線程,不關閉,一直持有。(缺省)
dubbo.protocol.threadpool=fixed
# 線程數量
dubbo.protocol.threads=500
#配置重試次數,最好只用於讀的重試,寫操做可能會引發屢次寫入 默認retries="0"
dubbo.provider.retries=0
# dubbo緩存文件
dubbo.cache=/data/dubbo/cache/dubbo-provider
#########################################################
# zookeeper config
zookeeper.connect=127.0.0.1:2181
複製代碼

測試 Dubbo

  1. 該接口需單獨打包,在服務提供方和消費方共享 ↩
  2. 對服務消費方隱藏實現 ↩
  3. 也可使用 IoC 注入 ↩

啓動 ZooKeeper

啓動服務

/opt/zookeeper-3.4.9/bin/zkServer.sh start
複製代碼

啓動提供方服務

package io.ymq.dubbo.provider.run;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

/**
 * 描述:啓動提供方服務
 *
 * @author yanpenglei
 * @create 2017-10-27 11:49
 **/
@SpringBootApplication
@ComponentScan(value = {"io.ymq.dubbo"})
public class Startup {

    public static void main(String[] args) {
        SpringApplication.run(Startup.class, args);
    }
}

複製代碼

測試消費遠程服務

package io.ymq.dubbo.test;

import io.ymq.dubbo.consumer.run.Startup;
import io.ymq.dubbo.consumer.service.ConsumerDemoService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/** * 描述: 測試消費遠程服務 * * @author yanpenglei * @create 2017-10-27 14:15 **/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Startup.class)
public class ConsumerTest {

    @Autowired
    private ConsumerDemoService consumerDemoService;

    @Test
    public void sayHello(){
        consumerDemoService.sayHello("Peng Lei");
    }
}
複製代碼

響應:

[15:54:00] Hello Peng Lei, request from consumer: /10.4.82.6:63993
複製代碼

代碼我已放到 Github ,導入spring-boot-dubbo 項目

github github.com/souyunku/sp…

Contact

  • 做者:鵬磊
  • 出處:www.ymq.io
  • Email:admin@souyunku.com
  • 版權歸做者全部,轉載請註明出處
  • Wechat:關注公衆號,搜雲庫,專一於開發技術的研究與知識分享

關注公衆號-搜雲庫
搜雲庫
相關文章
相關標籤/搜索