dubbo3.0整合SpringBoot例子
dubbo新版本(3.0以上)在相對於 dubbo 舊版本(2.5、2.6、2.7),有很多的不相同的地方。
官方文件也說了新版本的特性:
https://dubbo.apache.org/zh/docs/v3.0/new-in-dubbo3
本文就來使用dubbo3.0新版本 搭建一個dubbo+SpringBoot 專案,專案結構:
原始碼已上傳到github:https://github.com/DogerRain/dubbo-samples-test
(專案名字是帶springCloud的,因為本來還想整合SpringCloud的,還沒來得及整合.....先不改了)
下面是十分詳細的過程。
環境要求:
- jdk1.8
- zookeeper
專案會建立三個modul:
dubbo-samples-springcloud-api
dubbo-samples-springcloud-consumer
dubbo-samples-springcloud-provider
先來建立一個父專案,定義好一些 依賴包和專案結構:
<modules>
<module>dubbo-samples-springcloud-api</module>
<module>dubbo-samples-springcloud-consumer</module>
<module>dubbo-samples-springcloud-provider</module>
</modules>
<properties>
<java.version>1.8</java.version>
<source.level>1.8</source.level>
<target.level>1.8</target.level>
<skip_maven_deploy>true</skip_maven_deploy>
<spring-boot-dependencies.version>2.4.1</spring-boot-dependencies.version>
<spring-cloud-dependencies.version>Dalston.SR4</spring-cloud-dependencies.version>
<junit.version>4.12</junit.version>
<dubbo.version>3.0.2.1</dubbo.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 統一jar版本管理,避免使用 spring-boot-parent -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--dubbo 和 springboot 整合的包-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
專案的依賴結構為:
dubbo-samples-springcloud-consumer
--dubbo-samples-springcloud-api
dubbo-samples-springcloud-provider
--dubbo-samples-springcloud-api
dubbo-samples-springcloud-api
但如果是舊專案不想改動了,可能會不需要API專案那麼你的依賴結構就是這樣的:
dubbo-samples-springcloud-consumer
--dubbo-samples-springcloud-provider
dubbo-samples-springcloud-provider
1、建立 API 專案——dubbo-samples-springcloud-api
建立一個 dubbo-samples-springcloud-api
專案,建立該專案是為了解耦,這樣 provider定義好介面,打成一個SDK,丟給消費者引入就行了。
1.1、pom檔案:
<parent>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-samples-springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-samples-springcloud-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo-samples-springcloud-api</name>
<description>dubbo stress test - api</description>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
1.2、定義介面
廢話少說,先來定義一個介面:
UserService.java
介面:
public interface UserService {
User getUserInfo(long userId);
}
User.java
實體類:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = -4294369157631410325L;
Long userId;
String userName;
String responseInfo;
}
2、建立provider——dubbo-samples-springcloud-provider
建立一個dubbo-samples-springcloud-provider
專案
2.1、配置pom檔案:
<parent>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-samples-springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-samples-springcloud-provider</artifactId>
<dependencies>
<!--dubbo-samples-springcloud-api 專案 依賴-->
<dependency>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-samples-springcloud-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!--dubbo 與 spring-boot 整合包-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!--springboot 啟動核心包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--springboot rest -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
</dependency>
</dependencies>
使用了 dubbo-spring-boot-starter
就不需要 原來的 dubbo
依賴了,但是還是需要 dubbo-registry-zookeeper
,因為要連線zk。
2.2、yaml檔案配置
server:
port: 8090
spring:
application:
name: dubbo-samples-privider-springCloud
dubbo:
application:
name: ${spring.application.name}
registry:
address: zookeeper://127.0.0.1:2181
timeout: 2000
protocol:
name: dubbo
port: 20890
# 掃描 @DubboService 註解
scan:
base-packages: com.dubbo.service
dubbo.application.name
可以不寫,預設是 spring.application.name
的名字。
2.3、實現 UserService 介面
@DubboService
@Component
@Slf4j
public class UserServiceImpl implements UserService {
/**
*
* @param userId
* @return
* RPC provider 介面 實現
*/
@Override
public User getUserInfo(long userId) {
log.info("request from consumer: {}", RpcContext.getContext().getRemoteAddress());
log.info("response from provider: {}" , RpcContext.getContext().getLocalAddress());
return new User(userId, "userName" + userId , " --->>>>response from remote RPC provider:" + RpcContext.getContext().getLocalAddress());
}
}
@DubboService 表示這是一個暴露出去的介面。
舊版本可能是 使用 @Service ,與 spring的 @Service 容易讓人誤解,不推薦使用
@Component 表示這是一個bean,方便其他地方引用
2.4、新增一個Controller
我這裡用寫一個Controller,方便測試。
@RestController
@RequestMapping("/provider")
public class ProviderUserController {
@Resource
UserServiceImpl userService;
@RequestMapping("/user/{id}")
User getUserInfo(@PathVariable("id") Long id ){
return userService.getUserInfo(id);
}
}
2.5、啟動類
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
System.out.println("dubbo client started..........");
}
}
@EnableDubbo 表示自動掃描宣告 @DubboService 的類,也可以使用dubbo.scan.base-packages
指定掃描路徑,兩者選擇其中一個即可。
3、建立consumer——dubbo-samples-springcloud-consumer
3.1、配置pom檔案
<parent>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-samples-springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-samples-springcloud-consumer</artifactId>
<packaging>jar</packaging>
<description>The demo consumer module of dubbo project</description>
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>
<dependencies>
<!--dubbo-samples-springcloud-api 專案 依賴-->
<dependency>
<groupId>com.dubbo</groupId>
<artifactId>dubbo-samples-springcloud-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
</dependency>
</dependencies>
3.2、yaml配置
server:
port: 8091
spring:
application:
name: dubbo-samples-consumer-springCloud
dubbo:
registry:
address: zookeeper://127.0.0.1:2181
timeout: 2000
protocol:
name: dubbo
3.3、呼叫 provider
這一步我新增一個Controller 用來呼叫provider
@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerUserController {
@DubboReference(version = "*", protocol = "dubbo", loadbalance = "random")
private UserService userService;
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id") Long id) {
User user = userService.getUserInfo(id);
log.info("response from provider: {}", user);
return user;
}
}
@DubboReference 表示使用RPC(這裡使用dubbo協議)進行遠端呼叫。
3.4、啟動類
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
System.out.println("dubbo client started..........");
}
}
4、測試
4.1、啟動 provider
執行 ProviderApplication.java
埠是 8090
4.2、啟動 consumer
執行 ConsumerApplication.java
埠是 8091
4.3 登入 dubboAdmin看看
dubboAdmin 是一個後臺視覺化專案,可以看到 關於dubbo服務方、消費者相關的資訊。
這裡就不闡述怎麼搭建了,可以參考其他文章。
4.4、呼叫 consumer 的介面
瀏覽器輸入:http://localhost:8091/consumer/user/2
看下provider日誌:
2021-11-19 15:05:40.206 INFO 25932 --- [20890-thread-11] com.dubbo.service.UserServiceImpl: request from consumer: /172.16.44.48:50513
2021-11-19 15:05:40.206 INFO 25932 --- [20890-thread-11] com.dubbo.service.UserServiceImpl: response from provider: 172.16.44.48:20890
consumer日誌:
2021-11-19 15:05:40.207 INFO 33120 --- [nio-8091-exec-4] c.d.controller.ConsumerUserController: response from provider: User(userId=2, userName=userName2, responseInfo= --->>>>response from remote RPC provider:172.16.44.48:20890)
你會看到 consumer 啟動了一個 50513 的埠和provider進行通訊。
到這裡,dubbo+SpringBoot 的整合就完成了。
·
如果你直接呼叫provider的Controller。
瀏覽器輸入:http://localhost:8090/provider/user/2
它顯示是這樣的:
它就很普通的呼叫一樣了。
所以在這裡你對比一下,RPC也就是這樣的一個過程。
5、總結和踩坑
5.1、版本管理
建議使用dubbo的統一版本管理,也就是 dubbo-bom
5.2、jar依賴
如果你使用的是 dubbo-spring-boot-starter ,就不需要 dubbo 這個jar了
5.3、關聯
正常情況下, 這三個專案不是在一起的。
比如說公司兩個部門,一個是使用者中心,一個是訂單,使用者中心要RPC呼叫訂單服務。
那麼只需要訂單服務只需要新建一個API專案,定義一些介面。
然後打成jar 給到使用者中心接入,使用者中心使用Dubbo就可以直接呼叫了。
所以好處就是:
- 不需要使用Http直接呼叫了(當然Dubbo也支援http協議)
- 不需要整個jar打包,可以解耦,把api專案暴露即可
5.4、最後
專案的地址已經上傳到github:https://github.com/DogerRain/dubbo-samples-test
接下來還有兩個TODO:
- 整合SpringCloud
- 使用jmeter壓測dubbo、rest、hessian協議 傳輸大包的效能