Spring Boot-整合Dubbo
Dubbo官方網站: dubbo.apache.org/zh-cn/
前言
我將會用一個小demo來介紹如何與Spring Boot整合;
如果看我文章的朋友沒有用過Spring Boot,Dubbo,那麼我推薦你還是先去熟悉一下,因為本篇文章沒有介紹如何安裝。
這次的demo是獲取使用者訂單資訊的小demo
目前這個demo正在我的github上: github.com/aaaTao66/du…
開發環境
- win10
- idea 2019
- zookeeper
- dubbo
- jdk1.8
建立專案
- 首先我們建立一個maven專案非Spring Boot專案,這個專案的名字叫做 xxx-interface。
我這裡叫做:gmall-interface
根據 Dubbo的官方檔案的 服務最佳化實踐 裡面說的:
建議將服務介面、服務模型、服務異常等均放在 API 包中,因為服務模型和異常也是 API 的一部分,這樣做也符合分包原則:重用釋出等價原則(REP),共同重用原則(CRP)。
這就是我們建立 gmall-interface 的原因,也就是我們要把Java Bean 和 介面放在這個專案裡面,讓每一個微服務的專案依賴於它。
- 然後我們再建立兩個 Spring Boot的專案,一個提供者,一個消費者。
提供者專案名:boot-user-service-provider;(使用者,可以什麼都不勾選)
消費者專案名:boot-order-service-consumer;(訂單,記得初始化的時候要勾選web)
編寫程式
專案:gmall-interface
- 首先建立一個 JavaBean:
package com.carson.gmall.bean;
import java.io.Serializable;
public class UserAddress implements Serializable {
private Integer id;
private String userAddress; // 使用者地址
private String userId; // 使用者id
private String consignee; // 收貨人
private String phoneNum; // 電話號碼
private String isDefault; // 是否為預設地址 yes / no
// 省略get set toString 等方法
複製程式碼
記得要實現序列化
打個比方,如果我們的 A 客戶端 想要呼叫 B客戶端的一個方法,這個時候 A 伺服器要與B伺服器建立起連線,而且A伺服器呼叫方法的時候要還要傳入引數,而這個引數要在網路間傳遞,我們需要序列化。
然後B伺服器發現有外界的伺服器想要呼叫我的方法,同時還給我傳了引數,由於是序列化傳過來的,所以B伺服器要把引數反序列化。
然後方法呼叫完之後,還有一個返回值,這個時候基本與剛才一樣,先是序列化,然後A再把它反序列化,這樣就可以得到返回結果了。
- 建立介面
OrderService:
import com.carson.gmall.bean.UserAddress;
import java.util.List;
/**
* 使用者服務介面
* */
public interface UserService {
/*
按照使用者id返回所有收穫地址
* */
List<UserAddress> getUserAddressList(String userId);
}
複製程式碼
UserService:
import com.carson.gmall.bean.UserAddress;
import java.util.List;
/**
* 使用者服務介面
* */
public interface UserService {
/*
按照使用者id返回所有收穫地址
* */
List<UserAddress> getUserAddressList(String userId);
}
複製程式碼
- 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.carson.gmall</groupId>
<artifactId>gmall-interface</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
</project>
複製程式碼
提供者專案:boot-user-service-provider
- pom.xml
除了Spring Boot自帶的,還需要新增這兩個,dubbo的 0.2.0 版本是給Spring Boot 2.x用的。
如果Spring Boot是 1.x版本,那麼dubbo應該用 0.1.0.
與 gmall-interface 進行關聯。
<dependency>
<groupId>com.carson.gmall</groupId>
<artifactId>gmall-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
dubbo依賴
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
複製程式碼
然後就是Spring Boot的配置檔案:
- application.yml
dubbo:
application:
name: boot-order-service-consumer
registry:
address: zookeeper://127.0.0.1:2181
monitor:
protocol: registry
server:
port: 8081
複製程式碼
沒有用過可能看不懂這一段配置,其實對應的就是dubbo官方檔案的那一段 provider.xml :
具體網址 :dubbo.apache.org/zh-cn/docs/…
但是我的配置裡面沒有 宣告需要暴露的服務介面 ,這個等一下會說為什麼。
- UserService的實現類
import com.alibaba.dubbo.config.annotation.Service;
import com.carson.gmall.bean.UserAddress;
import com.carson.gmall.bootuserserviceprovider.service.UserService;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Service // 暴露服務
@Component
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
UserAddress address1 = new UserAddress(1,"河北省衡水市","1","carson","12345678911","Y");
UserAddress address2 = new UserAddress(1,"山東省德州市","2","eason","4562144","Y");
return Arrays.asList(address1,address2);
}
}
複製程式碼
注意我的註解 @Service,這個註解不是Spring的,而是dubbo的:
import com.alibaba.dubbo.config.annotation.Service;
這個註解的意思就是:宣告需要暴露的服務介面;
這個方法我們可以看到我設定了兩個收穫地址,並且把它以list方式返回。
- Spring Boot主類
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo // 開啟基於註解的dubbo功能
@SpringBootApplication
public class BootUserServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(BootUserServiceProviderApplication.class,args);
}
}
複製程式碼
消費者專案:boot-order-service-consumer
pom 檔案與剛才的提供者一樣。
- application.yml
dubbo:
application:
name: boot-order-service-consumer
registry:
address: zookeeper://127.0.0.1:2181
monitor:
protocol: registry
server:
port: 8081
複製程式碼
具體配的什麼,可以參考duboo官方檔案的快速啟動,也就是剛才上面的網址:
- OrderServiceImpl
package com.carson.gmall.bootorderserviceconsumer.service.impl;
import com.alibaba.dubbo.config.annotation.Reference;
import com.carson.gmall.bean.UserAddress;
import com.carson.gmall.bootuserserviceprovider.service.OrderService;
import com.carson.gmall.bootuserserviceprovider.service.UserService;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 1. 將服務提供者註冊到註冊中心(暴漏服務)
* 1) 匯入 dubbo 依賴
* 2) 配置服務提供者
*
* 2. 讓服務消費者去註冊中心訂閱服務提供者的服務地址
* */
@Service
public class OrderServiceImpl implements OrderService {
@Reference
UserService userService;
public List<UserAddress> initOrder(String userId) {
System.out.println("使用者id:"+userId);
// 1. 查詢使用者的收貨地址
List<UserAddress> userAddressList = userService.getUserAddressList(userId);
return userAddressList;
}
}
複製程式碼
注意 @Reference: 遠端呼叫UserService,自己會去註冊中心去發現
- OrderController
@Controller
public class OrderController {
@Autowired
private OrderService orderService;
@ResponseBody
@RequestMapping("/initOrder")
public List<UserAddress> initOrder(@RequestParam("uid") String userId) {
return orderService.initOrder(userId);
}
}
複製程式碼
@ResponseBody: 把獲取到的結果以 json方式響應
- 啟動類
@EnableDubbo // 開啟基於註解的dubbo功能
@SpringBootApplication
public class BootOrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(BootOrderServiceConsumerApplication.class,args);
}
}
複製程式碼
和提供者一樣
啟動zookeeper和dubbo和這兩個專案,可以在dubbo控制檯看到,已經有了消費者和提供者
然後,我們剛才啟動的Spring Boot,有一個是web專案,並且設定了埠 8081,讓我們試著訪問這個 8081埠,並且帶上引數:
成功獲取到了訂單資訊;