Dubbo學習記錄(二)Dubbo實現RPC簡單實例

前言

 本文主要接着 上篇 接着Dubbo學習記錄(一)zookeeper、dubbo-admin管理平臺安裝部署來基於springboot用dubbo寫了一個RPC簡單的實例:實現創建一個簡單的服務接口,然後在dubbo的服務端實現該接口並向zookeeper服務器進行註冊,客戶端向zookeeper服務器訂閱該接口並使用。同時,也介紹了一下dubbo,總結了一下spring通過xml配置使用dubbo,並收集和提供了一些相關資料方便查閱。

 本文完整源碼已上傳至github:https://github.com/leon2016/dubbo-parent

Dubbo簡介

官網(中文):http://dubbo.apache.org/zh-cn/
git源碼:https://github.com/apache/incubator-dubbo.git
官方文檔:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html (必讀)
dubbo-admin:https://github.com/apache/incubator-dubbo-admin/tree/master
dubbo-admin打好的war包:https://pan.baidu.com/s/1UuCWpUeTm0riumnKmKE2eg 密碼:e5ic

Dubbo是什麼

 Dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分佈式的需求,其實是不需要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求,並且本質上是個服務調用的東東,說白了就是個遠程服務調用的分佈式框架(告別Web Service模式中的WSdl,以服務者與消費者的方式在dubbo上註冊)

Dubbo能做什麼

  • 遠程通訊:透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
  • 集羣容錯:軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
  • 自動發現:服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,並且能夠平滑添加或刪除服務提供者。

特性

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

在這裏插入圖片描述

架構

在這裏插入圖片描述

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

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

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

基本應用

如圖,系統A通過系統B查詢數據庫獲得數據:
在這裏插入圖片描述

更多dubbo自身技術選型及原理可參考官方文檔,很詳細的。

 


通過註解使用dubbo實例(springboot版)

1.創建Maven項目(分模塊)

(1)新建Maven Project : dubbo-parent (作爲父級模塊)
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
(2)新建Maven Module:egg-api (服務端、客戶端共享的接口模塊)
在這裏插入圖片描述
在這裏插入圖片描述
(3)同理,新建Maven Module:egg-provider(服務端)、egg-consumer(客戶端)
在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

(4)目錄結構
 下面是我的項目最終目錄結構:
在這裏插入圖片描述

2.配置依賴(pom.xml)

dubbo-parent/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>
	<groupId>com.leon</groupId>
	<artifactId>dubbo-parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>
	<modules>
		<module>egg-api</module>
		<module>egg-provider</module>
		<module>egg-consumer</module>
	</modules>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<curator-framework.version>4.0.1</curator-framework.version>
		<zookeeper.version>3.4.13</zookeeper.version>
		<dubbo.starter.version>0.2.0</dubbo.starter.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>${dubbo.starter.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>${curator-framework.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>${zookeeper.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

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

</project>

egg-api/pom.xml:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.leon</groupId>
		<artifactId>dubbo-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>egg-api</artifactId>
	<name>egg-api</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<executions>
					<execution>
						<phase>none</phase>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

egg-provider/pom.xml:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.leon</groupId>
		<artifactId>dubbo-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>egg-provider</artifactId>
	<name>egg-provider</name>
	<url>http://maven.apache.org</url>

	<dependencies>
		<dependency>
			<groupId>com.leon</groupId>
			<artifactId>egg-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>

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


</project>

dubbo-consumer/pom.xml:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.leon</groupId>
		<artifactId>dubbo-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>egg-consumer</artifactId>
	<name>egg-consumer</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.leon</groupId>
			<artifactId>egg-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

配置完pom.xml,更新一下maven項目:右鍵dubbo-parent>maven->update project…
在這裏插入圖片描述

3.配置dubbo屬性(application.properties)

(1)服務提供方(服務端)dubbo配置
 新建/egg-provider/src/main/resources/application.properties:


#服務器端口配置
spring.application.name = dubbo-provider
server.port = 9090

#提供方應用名稱,用於計算依賴關係(同樣的服務名字相同,不要和別的服務同名,下面這4個個結合@service註解是dubbo核心配置)
dubbo.application.name = dubbo-provider
#指定註冊中心的位置,使用zookeeper註冊中心暴露服務地址
dubbo.registry.address = zookeeper://localhost:2181
#用dubbo協議在20880端口暴露服務
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880


#統一設置服務提供方的規則
dubbo.provider.timeout = 2000

#服務提供方版本號
demo.service.version = 1.0.0

 
(2)服務消費方(客戶端)dubbo配置
 新建/egg-consumer/src/main/resources/application.properties:

#服務器端口配置
spring.application.name = dubbo-consumer
server.port = 9091

#服務消費方方應用名稱,用於計算依賴關係(同樣的服務名字相同,不要和別的服務同名,下面這4個個結合@service註解是dubbo核心配置)
dubbo.application.name = egg-consumer
#指定註冊中心的位置,使用zookeeper註冊中心暴露服務地址
dubbo.registry.address = zookeeper://localhost:2181
#用dubbo協議在20880端口暴露服務
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880

#統一設置服務消費方的規則
dubbo.provider.timeout = 2000

#調用的服務提供方的版本號
demo.service.version = 1.0.0

4.定義服務接口

新建/egg-api/src/main/java/com/leon/api/service/IHelloworldService.java:

package com.leon.api.service;

/**
 * API接口
 * 
 * @author leon
 *
 */
public interface IHelloworldService {
	String dubbo();
}

5.服務端實現接口

新建/egg-provider/src/main/java/com/leon/provider/service/impl/HelloworldImpl.java:

package com.leon.provider.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.leon.api.service.IHelloworldService;

/**
 * 服務提供方實現API接口
 * 
 * 註解"@service" 聲明需要暴露的服務接口
 * 
 * 
 * @author leon
 *
 */
@Service(version = "${demo.service.version}")
public class HelloworldImpl implements IHelloworldService {

	@Override
	public String dubbo() {

		return "hello world!";

	}

}

爲了springboot方式啓動服務端,新建一個啓動類
/egg-provider/src/main/java/com/leon/provider/EggProviderApplication.java:

package com.leon.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

/**
 * 服務提供啓動類
 * 
 * "@EnableDubbo"開啓dubbo支持
 * 
 * @author leon
 *
 */
@EnableDubbo
@SpringBootApplication
public class EggProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(EggProviderApplication.class, args);
	}
}
6.客戶端引用接口

新建/egg-consumer/src/main/java/com/leon/consumer/controller/ConsumerController.java:

package com.leon.consumer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.leon.api.service.IHelloworldService;

/**
 * 服務消費方
 * 
 * 註解"@Reference(version = "${demo.service.version}")"引用服務方提供的接口
 * 
 * @author leon
 */
@RestController
public class ConsumerController {
	@Reference(version = "${demo.service.version}")
	private IHelloworldService helloWorld;

	@RequestMapping("/dubbo/helloWorld")
	public String helloWorld() {
		return helloWorld.dubbo();
	}
}

爲了springboot方式啓動客戶端,新建一個啓動類
/egg-consumer/src/main/java/com/leon/consumer/EggConsumerApplication.java:

package com.leon.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

/**
 * 服務消費方啓動類
 * 
 * "@EnableDubbo"開啓dubbo支持
 * 
 * @author leon
 *
 */
@EnableDubbo
@SpringBootApplication
public class EggConsumerApplication {

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

7.啓動項目

(1)先啓動服務端:右鍵EggProviderApplication.java執行main函數
在這裏插入圖片描述
(2)再啓動客戶端:右鍵EggConsumerApplication.java執行main函數

(3)訪問:http://localhost:9091/dubbo/helloWorld/
打印:hello world !代表egg-consumer成功調用egg-consumer的HelloWorldImpl.dubbo()
在這裏插入圖片描述
(4)訪問dubbo-admin:http://localhost:8080/dubbo-admin-2.6.0/
home頁紅框 stat顯示了當前服務方與消費方狀態:
在這裏插入圖片描述
點擊services可以看到所有註冊的接口:
在這裏插入圖片描述
點擊接口可以查看詳情:
在這裏插入圖片描述

8.源碼

本文完整源碼已上傳
至github:https://github.com/leon2016/dubbo-parent


參考文獻

https://www.cnblogs.com/gengaixue/p/8976891.html


後記

一波走下來,發現dubbo真的很優秀,學習曲線也還比較平滑。
by the way, 要在spring中通過xml配置使用dubbo的話,
可以參考官方文檔
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html

https://blog.csdn.net/smilefyx/article/details/71024394

XML方式使用dubbo核心配置如下:

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章