Apache Dubbo
是一款高性能、輕量級的開源 Java
RPC
框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。java
注意,是
Apache Dubbo
,再也不是Alibaba Dubbo
。簡單來講就是Alibaba
將Dubbo
移交給Apache
開源社區進行維護。參見 dubbo-spring-boot-projectgit
Spring Boot 系列:整合 Alibaba Dubbogithub
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>
order
:管理工程信息;order-api
:定義RPC
服務的接口、參數以及響應結果的結果集;order-provider
:RPC
服務的提供端;order-consumer
:RPC
服務的消費端,實際開發過程當中實際狀況是其它服務的調用該訂單RPC
服務order
我這裏爲了和以前老版本的
alibaba
的dubbo
項目區分,文件名取爲apache-dubbo-demo
,maven
項目名稱爲order
。web
該項目主要做用是定義工程信息、管理整個項目依賴版本等等,因此src
目錄不須要。spring
pom.xml
根工程中使用了<dependencyManagement>
和<dependencies>
進行依賴管理。apache
<dependencyManagement>
:聲明全局依賴,當子項目指定引用纔會繼承依賴;<dependencies>
:聲明全局依賴,子項目直接自動繼承依賴。<?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>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 根項目</description> <!--配置--> <properties> <java.version>1.8</java.version> <dubbo.version>2.7.5</dubbo.version> <zookeeper.version>3.4.14</zookeeper.version> </properties> <!-- 子項目 --> <modules> <module>order-api</module> <module>order-provider</module> <module>order-consumer</module> </modules> <!--聲明全局依賴(子項目須要顯示的引用纔會繼承依賴)--> <dependencyManagement> <dependencies> <!-- dubbo-start依賴 --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>${dubbo.version}</version> </dependency> <!--zookeeper 註冊中心客戶端引入 使用的是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> <!--聲明全局依賴(子項目不須要顯示的引用,自動繼承依賴)--> <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
無需更多依賴,因此很簡單。json
<?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公共項目</description> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
RPC
結果集ResultCodeEnum.java
public enum ResultCodeEnum { /*** 通用部分 100 - 599***/ // 成功請求 SUCCESS(200, "successful"), /*** 這裏能夠根據不一樣模塊用不一樣的區級分開錯誤碼,例如: ***/ // 1000~1999 區間表示用戶模塊錯誤 // 2000~2999 區間表示訂單模塊錯誤 // 3000~3999 區間表示商品模塊錯誤 // 。。。 ORDER_NOT_FOUND(2000, "order not found"), ; /** * 響應狀態碼 */ private Integer code; /** * 響應信息 */ 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; } }
RpcResult.java
public class RpcResult <T> implements Serializable { /** * 是否響應成功 */ private Boolean success; /** * 響應狀態碼 */ private Integer code; /** * 響應數據 */ private T data; /** * 錯誤信息 */ private String message; // 構造器開始 /** * 無參構造器(構造器私有,外部不能夠直接建立) */ private RpcResult() { this.code = 200; this.success = true; } /** * 有參構造器 * @param obj */ private RpcResult(T obj) { this.code = 200; this.data = obj; this.success = true; } /** * 有參構造器 * @param resultCode */ private RpcResult(ResultCodeEnum resultCode) { this.success = false; this.code = resultCode.getCode(); this.message = resultCode.getMessage(); } // 構造器結束 /** * 通用返回成功(沒有返回結果) * @param <T> * @return */ public static<T> RpcResult<T> success(){ return new RpcResult(); } /** * 返回成功(有返回結果) * @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 + '\'' + '}'; } }
RPC
接口public interface OrderDubboService { RpcResult<OrderDomain> getOrder(); }
實體
OrderDomain.java
挺簡單的,詳見Github
倉庫。api
order-provider
此子項目是一個服務類項目,也就是將接口服務註冊到zookeeper
註冊中心供消費端調取使用。瀏覽器
<?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 服務提供者</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>
@Service public class OrderDubboServiceImpl implements OrderDubboService { @Override public RpcResult<OrderDomain> getOrder() { return RpcResult.success(new OrderDomain(1, 10086, LocalDateTime.now())); } }
注意:
@Service
是 dubbo
包下面的註解不是 Spring
裏面的註解。springboot
dubbo
的配置直接用 dubbo
,再也不以 Spring
開頭;base-packages
:指定接口實現所在路徑。server: # 服務端口 port: 7777 spring: application: name: order-provider # dubbo 相關配置(dubbo 的配置再也不以 Spring 開頭) dubbo: application: # 應用名稱 name: order-provider scan: # 接口實現者(服務實現)包 base-packages: cn.van.order.service.impl # 註冊中心信息 registry: address: zookeeper://127.0.0.1:2181 protocol: # 協議名稱 name: dubbo # 協議端口 port: 20880
order-consumer
此子項目就是一個消費項目,好比商品模塊、財務模塊等等。
<?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 消費者</description> <dependencies> <dependency> <groupId>cn.van.order</groupId> <artifactId>order-api</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <!-- web項目依賴 --> <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>
模擬一個接口獲取訂單詳情。
@RestController @RequestMapping("/order") public class OrderConsumerController { @Reference OrderDubboService orderDubboService; @GetMapping("getOrder") public RpcResult getOrder() { return orderDubboService.getOrder(); } }
注意:@Reference
引入的是 Dubbo
接口,因此是 Dubbo
的註解。
server: port: 7000 spring: application: name: order-consumer # dubbo 相關配置 dubbo: application: name: order-consumer registry: address: zookeeper://127.0.0.1:2181
一切就緒,若是在order-consumer
的測試接口能成功請求到數據,則證實 Dubbo
服務搭建成功。
zookeeper
咱們選用zookeeper
做爲註冊中心,所以啓動項目以前須要先啓動它。
dubbo-admin
dubbo-admin
便於觀察 order-provider
是否成功將接口註冊,具體安裝步驟詳見apache/dubbo-admin
默認端口:
8080
。
dubbo-provider
成功啓動後能夠在dubbo-admin
:已經成功將接口 OrderService
註冊到 zookeeper
上以下:
成功將藉口註冊到註冊中心,說明dubbo-provider
註冊成功。
order-cosumer
啓動消費者項目,在瀏覽器請求消費接口:http://localhost:7000/order/getOrder,成功返回數據以下:
{ "success":true, "code":200, "data":{ "id":1, "orderNum":10086, "gmtCreate":"2020-05-06T11:59:45.535" }, "message":null }
成功請求到 order-provider
提供的數據,說明 Dubbo
搭建成功!
以上的完整代碼我已上傳到 Github,須要的能夠自取測試,歡迎star
!