Spring Boot 整合 Apache Dubbo的示例代碼
Apache Dubbo
是一款高性能、輕量級(jí)的開源 Java
RPC
框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。
注意,是 Apache Dubbo
,不再是 Alibaba Dubbo
。簡(jiǎn)單來說就是 Alibaba
將 Dubbo
移交給 Apache
開源社區(qū)進(jìn)行維護(hù)。參見 dubbo-spring-boot-project
Spring Boot 系列:整合 Alibaba Dubbo
一、本文示例說明
1.1 框架版本Dubbo
版本
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.5</version> </dependency>
Spring Boot
版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> </parent>
1.2 模塊關(guān)系
- 根工程
order
:管理工程信息; - 子工程
order-api
:定義RPC
服務(wù)的接口、參數(shù)以及響應(yīng)結(jié)果的結(jié)果集; - 子工程
order-provider
:RPC
服務(wù)的提供端; - 子工程
order-consumer
:RPC
服務(wù)的消費(fèi)端,實(shí)際開發(fā)過程中實(shí)際情況是其它服務(wù)的調(diào)用該訂單RPC
服務(wù)
二、根工程
2.1 創(chuàng)建項(xiàng)目 order
我這里為了和之前老版本的alibaba
的dubbo
項(xiàng)目區(qū)分,文件名取為apache-dubbo-demo
,maven
項(xiàng)目名稱為order
。
該項(xiàng)目主要作用是定義工程信息、管理整個(gè)項(xiàng)目依賴版本等等,所以src
目錄不需要。
2.2 pom.xml
根工程中使用了<dependencyManagement>
和<dependencies>
進(jìn)行依賴管理。
<dependencyManagement>
:聲明全局依賴,當(dāng)子項(xiàng)目指定引用才會(huì)繼承依賴;<dependencies>
:聲明全局依賴,子項(xiàng)目直接自動(dòng)繼承依賴。
<?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> <!-- 父級(jí)引用 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> </parent> <!-- 基本信息 --> <groupId>cn.van.order</groupId> <artifactId>order</artifactId> <version>1.0.0-SNAPSHOT</version> <name>${project.artifactId}</name> <description>Apache Dubbo 根項(xiàng)目</description> <!--配置--> <properties> <java.version>1.8</java.version> <dubbo.version>2.7.5</dubbo.version> <zookeeper.version>3.4.14</zookeeper.version> </properties> <!-- 子項(xiàng)目 --> <modules> <module>order-api</module> <module>order-provider</module> <module>order-consumer</module> </modules> <!--聲明全局依賴(子項(xiàng)目需要顯示的引用才會(huì)繼承依賴)--> <dependencyManagement> <dependencies> <!-- dubbo-start依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>${dubbo.version}</version> </dependency> <!--zookeeper 注冊(cè)中心客戶端引入 使用的是curator客戶端 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>${dubbo.version}</version> <type>pom</type> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement> <!--聲明全局依賴(子項(xiàng)目不需要顯示的引用,自動(dòng)繼承依賴)--> <dependencies> <!-- spring boot 依賴 --> <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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <!-- 打包插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
三、order-api
3.1 項(xiàng)目依賴
無需更多依賴,所以很簡(jiǎn)單。
<?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>cn.van.order</groupId> <artifactId>order</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <groupId>cn.van.order</groupId> <artifactId>order-api</artifactId> <version>1.0.0-SNAPSHOT</version> <name>${project.artifactId}</name> <description>dubbo公共項(xiàng)目</description> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2 封裝 RPC
結(jié)果集先封裝一個(gè)返回碼枚舉類ResultCodeEnum.java
public enum ResultCodeEnum { /*** 通用部分 100 - 599***/ // 成功請(qǐng)求 SUCCESS(200, "successful"), /*** 這里可以根據(jù)不同模塊用不同的區(qū)級(jí)分開錯(cuò)誤碼,例如: ***/ // 1000~1999 區(qū)間表示用戶模塊錯(cuò)誤 // 2000~2999 區(qū)間表示訂單模塊錯(cuò)誤 // 3000~3999 區(qū)間表示商品模塊錯(cuò)誤 // 。。。 ORDER_NOT_FOUND(2000, "order not found"), ; /** * 響應(yīng)狀態(tài)碼 */ private Integer code; /** * 響應(yīng)信息 */ private String message; ResultCodeEnum(Integer code, String msg) { this.code = code; this.message = msg; } public Integer getCode() { return code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
先封裝一個(gè)RPC 響應(yīng)結(jié)果集RpcResult.java
public class RpcResult <T> implements Serializable { /** * 是否響應(yīng)成功 */ private Boolean success; /** * 響應(yīng)狀態(tài)碼 */ private Integer code; /** * 響應(yīng)數(shù)據(jù) */ private T data; /** * 錯(cuò)誤信息 */ private String message; // 構(gòu)造器開始 /** * 無參構(gòu)造器(構(gòu)造器私有,外部不可以直接創(chuàng)建) */ private RpcResult() { this.code = 200; this.success = true; } /** * 有參構(gòu)造器 * @param obj */ private RpcResult(T obj) { this.code = 200; this.data = obj; this.success = true; } /** * 有參構(gòu)造器 * @param resultCode */ private RpcResult(ResultCodeEnum resultCode) { this.success = false; this.code = resultCode.getCode(); this.message = resultCode.getMessage(); } // 構(gòu)造器結(jié)束 /** * 通用返回成功(沒有返回結(jié)果) * @param <T> * @return */ public static<T> RpcResult<T> success(){ return new RpcResult(); } /** * 返回成功(有返回結(jié)果) * @param data * @param <T> * @return */ public static<T> RpcResult<T> success(T data){ return new RpcResult<T>(data); } /** * 通用返回失敗 * @param resultCode * @param <T> * @return */ public static<T> RpcResult<T> failure(ResultCodeEnum resultCode){ return new RpcResult<T>(resultCode); } public Boolean getSuccess() { return success; } public void setSuccess(Boolean success) { this.success = success; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public T getData() { return data; } public void setData(T data) { this.data = data; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { return "RpcResult{" + "success=" + success + ", code=" + code + ", data=" + data + ", message='" + message + '\'' + '}'; } }
3.3 編寫一個(gè) RPC
接口
public interface OrderDubboService { RpcResult<OrderDomain> getOrder(); }
實(shí)體OrderDomain.java
挺簡(jiǎn)單的,詳見 Github
倉庫。
四、order-provider
此子項(xiàng)目是一個(gè)服務(wù)類項(xiàng)目,也就是將接口服務(wù)注冊(cè)到zookeeper
注冊(cè)中心供消費(fèi)端調(diào)取使用。
4.1 項(xiàng)目依賴
<?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>cn.van.order</groupId> <artifactId>order</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <groupId>cn.van.order</groupId> <artifactId>order-provider</artifactId> <version>1.0-SNAPSHOT</version> <name>${project.artifactId}</name> <description>Dubbo 服務(wù)提供者</description> <dependencies> <dependency> <groupId>cn.van.order</groupId> <artifactId>order-api</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- zookeeper依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>${dubbo.version}</version> <type>pom</type> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
4.2 服務(wù)實(shí)現(xiàn)接口
@Service public class OrderDubboServiceImpl implements OrderDubboService { @Override public RpcResult<OrderDomain> getOrder() { return RpcResult.success(new OrderDomain(1, 10086, LocalDateTime.now())); } }
注意:
@Service
是 dubbo
包下面的注解不是 Spring
里面的注解。
4.3 項(xiàng)目配置
dubbo
的配置直接用dubbo
,不再以Spring
開頭;base-packages
:指定接口實(shí)現(xiàn)所在路徑。
server: # 服務(wù)端口 port: 7777 spring: application: name: order-provider # dubbo 相關(guān)配置(dubbo 的配置不再以 Spring 開頭) dubbo: application: # 應(yīng)用名稱 name: order-provider scan: # 接口實(shí)現(xiàn)者(服務(wù)實(shí)現(xiàn))包 base-packages: cn.van.order.service.impl # 注冊(cè)中心信息 registry: address: zookeeper://127.0.0.1:2181 protocol: # 協(xié)議名稱 name: dubbo # 協(xié)議端口 port: 20880
五、order-consumer
此子項(xiàng)目就是一個(gè)消費(fèi)項(xiàng)目,比如商品模塊、財(cái)務(wù)模塊等等。
5.1 項(xiàng)目依賴
<?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>cn.van.order</groupId> <artifactId>order</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <groupId>cn.van.order</groupId> <artifactId>order-consumer</artifactId> <version>1.0-SNAPSHOT</version> <name>${project.artifactId}</name> <description>Dubbo 消費(fèi)者</description> <dependencies> <dependency> <groupId>cn.van.order</groupId> <artifactId>order-api</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <!-- web項(xiàng)目依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- dubbo依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- dubbo的zookeeper依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>${dubbo.version}</version> <type>pom</type> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
5.2 測(cè)試接口
模擬一個(gè)接口獲取訂單詳情。
@RestController @RequestMapping("/order") public class OrderConsumerController { @Reference OrderDubboService orderDubboService; @GetMapping("getOrder") public RpcResult getOrder() { return orderDubboService.getOrder(); } }
注意:@Reference
引入的是 Dubbo
接口,所以是 Dubbo
的注解。
5.3 配置文件
server: port: 7000 spring: application: name: order-consumer # dubbo 相關(guān)配置 dubbo: application: name: order-consumer registry: address: zookeeper://127.0.0.1:2181
六、測(cè)試
一切就緒,如果在order-consumer
的測(cè)試接口能成功請(qǐng)求到數(shù)據(jù),則證明 Dubbo
服務(wù)搭建成功。
6.1 啟動(dòng) zookeeper
我們選用zookeeper
作為注冊(cè)中心,因此啟動(dòng)項(xiàng)目之前需要先啟動(dòng)它。
6.2 dubbo-admin
dubbo-admin
便于觀察 order-provider
是否成功將接口注冊(cè),具體安裝步驟詳見apache/dubbo-admin
默認(rèn)端口:8080
。
6.3 啟動(dòng) dubbo-provider
成功啟動(dòng)后可以在dubbo-admin
:已經(jīng)成功將接口 OrderService
注冊(cè)到 zookeeper
上如下:
成功將借口注冊(cè)到注冊(cè)中心,說明dubbo-provider
注冊(cè)成功。
6.4 啟動(dòng) order-cosumer
啟動(dòng)消費(fèi)者項(xiàng)目,在瀏覽器請(qǐng)求消費(fèi)接口:http://localhost:7000/order/getOrder,成功返回?cái)?shù)據(jù)如下:
{ "success":true, "code":200, "data":{ "id":1, "orderNum":10086, "gmtCreate":"2020-05-06T11:59:45.535" }, "message":null }
成功請(qǐng)求到 order-provider
提供的數(shù)據(jù),說明 Dubbo
搭建成功!
七、總結(jié)
以上的完整代碼我已上傳到 Github,需要的可以自取測(cè)試,歡迎star
!
相關(guān)文章
MybatisPlus如何調(diào)用count函數(shù)
這篇文章主要介紹了MybatisPlus如何調(diào)用count函數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08深入解析Java的Hibernate框架中的一對(duì)一關(guān)聯(lián)映射
這篇文章主要介紹了Java的Hibernate框架的一對(duì)一關(guān)聯(lián)映射,包括對(duì)一對(duì)一外聯(lián)映射的講解,需要的朋友可以參考下2016-01-01使用Spring Data Redis實(shí)現(xiàn)數(shù)據(jù)緩存的方法
目前在系統(tǒng)架構(gòu)設(shè)計(jì)中使用Redis實(shí)現(xiàn)緩存,這篇文章主要介紹了使用Spring Data Redis實(shí)現(xiàn)數(shù)據(jù)緩存的方法,具有一定的參考價(jià)值,需要的朋友可以參考下2018-11-11Java并發(fā)中的ABA問題學(xué)習(xí)與解決方案
這篇文章主要介紹了Java并發(fā)中的ABA問題學(xué)習(xí)與解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05DoytoQuery中關(guān)于N+1查詢問題解決方案詳解
這篇文章主要為大家介紹了DoytoQuery中關(guān)于N+1查詢問題解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Java 8 lambda表達(dá)式引入詳解及實(shí)例
這篇文章主要介紹了Java 8 lambda表達(dá)式引入詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05SpringBoot指標(biāo)監(jiān)控功能實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot指標(biāo)監(jiān)控功能實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06