一、前言
上篇介紹了 Redis 的集成過程,可用於解決熱點數據訪問的性能問題。隨着業務復雜度的提高,單體應用越來越龐大,就好比一個類的代碼行數越來越多,分而治之,切成多個類應該是更好的解決方法,所以一個龐大的單體應用分出多個小應用也更符合這種分治的思想。於是乎微服務化的概念油然而生,微服務化的第一步就是選擇適用的分布式服務框架,基於團隊成員有使用過「 Dubbo 」的經驗,我們放棄了完全陌生的「 Spring Cloud 」。本篇將主要介紹在 Spring Boot 中集成 Dubbo 的過程。
二、集成 Dubbo
2.1 引入 Dubbo 依賴包
① 首先在項目父 pom 文件中聲明 Dubbo 依賴。
<dependencyManagement>
<dependencies>
...省略其余部分...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
</dependencyManagement>
② 其次在 demo-biz 層中的 pom 文件添加上述 Dubbo 依賴。
<dependencies>
...省略其余部分...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
</dependencies>
2.2 添加 Dubbo 常用配置項
在 application.properties 文件中的添加 Dubbo 相關的配置項:
# 當前應用名稱,用於注冊中心計算應用間依賴關系
dubbo.application.name = demo
# 組織名稱,用於注冊中心區分服務來源
dubbo.application.organization = example
# 應用負責人,用於服務治理
dubbo.application.owner = linjian
# 注冊中心地址協議
dubbo.registry.protocol = zookeeper
# 注冊中心服務器地址
dubbo.registry.address = 127.0.0.1:2181
# 協議名稱
dubbo.protocol.name = dubbo
# 服務端口
dubbo.protocol.port = 20880
# 服務版本
dubbo.provider.version = 1.0.0.dev
# 遠程服務調用超時時間(毫秒)
dubbo.provider.timeout = 60000
# 啟動時檢查提供者是否存在
dubbo.consumer.check = false
注:詳細配置見 官方配置參考手冊
三、接口服務化
3.1 Dubbo 接口編程規約
- Dubbo 接口類以 Rpc 為前綴命名並剝離出一個單獨的模塊,稱之為遠程服務層
- 請求參數類以 Param 為后綴命名並統一存放於「 param 」目錄
- 返回結果類以 DTO 為后綴命名並統一存放於「 result 」目錄
還有一條重要規則下篇「統一接口返回值」再說明
3.2 創建遠程服務層
① 首先按照該篇博客 Spring Boot 項目實戰(一)Maven 多模塊項目搭建 中的「4.2 創建子模塊」一節添加「 demo-remote 」子模塊。
② 其次在項目父 pom 文件的 dependencyManagement 標簽中聲明 demo-remote 子模塊的依賴。
<dependency>
<groupId>com.example.demo</groupId>
<artifactId>demo-remote</artifactId>
<version>${demo.version}</version>
</dependency>
③ 然后在 demo-biz 層中的 pom 文件中添加 demo-remote 依賴。
<dependencies>
...省略其余部分...
<dependency>
<groupId>com.example.demo</groupId>
<artifactId>demo-remote</artifactId>
</dependency>
</dependencies>
由於 demo-remote 層最終是要打成一個 JAR 包供外部引入,而其接口的內部實現還是需要寫在 demo-biz 層,所以我們將這兩個模塊之間建立了依賴關系,並在 demo-biz 層 com.example.demo.biz.service.impl 包中,新建 remote 目錄存放 demo-remote 層遠程服務接口的具體實現。
④ 在 DemoWebApplication 入口類中增加 Dubbo 接口實現類包掃描,設置 @DubboComponentScan 注解中的 basePackages 值為 com.example.demo.biz.service.impl.remote
@DubboComponentScan(basePackages = "com.example.demo.biz.service.impl.remote")
3.3 簡易 Dubbo 接口測試
配置完模塊間的依賴關系后,我們通過一個簡易的 Dubbo 接口測試是否可用。
① 首先在 demo-remote 層的 pom 文件中添加必要的 lombok 依賴
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
① 其次在該層創建 com.example.demo.remote 包,添加 param 目錄並在其中創建 DemoParam 請求參數類,添加 result 目錄並在其中創建 DemoDTO 返回結果類,添加 service 目錄並在其中創建 RpcDemoService 接口類。
package com.example.demo.remote.model.param;
import lombok.Data;
import java.io.Serializable;
/**
* @author linjian
* @date 2019/3/15
*/
@Data
public class DemoParam implements Serializable {
private Integer id;
}
package com.example.demo.remote.model.result;
import lombok.Data;
import java.io.Serializable;
/**
* @author linjian
* @date 2019/3/15
*/
@Data
public class DemoDTO implements Serializable {
private Integer id;
private String name;
}
package com.example.demo.remote.service;
import com.example.demo.remote.model.param.DemoParam;
import com.example.demo.remote.model.result.DemoDTO;
/**
* @author linjian
* @date 2019/3/15
*/
public interface RpcDemoService {
/**
* Dubbo 接口測試
*
* @param param DemoParam
* @return DemoDTO
*/
DemoDTO test(DemoParam param);
}
② 在 demo-biz 層 com.example.demo.biz.service.impl.remote 包中新建 RpcDemoServiceImpl 接口實現類。
package com.example.demo.biz.service.impl.remote;
import com.alibaba.dubbo.config.annotation.Service;
import com.example.demo.biz.service.DemoService;
import com.example.demo.remote.model.param.DemoParam;
import com.example.demo.remote.model.result.DemoDTO;
import com.example.demo.remote.service.RpcDemoService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author linjian
* @date 2019/3/15
*/
@Service
public class RpcDemoServiceImpl implements RpcDemoService {
@Autowired
private DemoService demoService;
@Override
public DemoDTO test(DemoParam param) {
DemoDTO demo = new DemoDTO();
demo.setId(1);
demo.setName(demoService.test());
return demo;
}
}
③ 運行 DemoWebApplication 啟動類的 main 方法,查看控制台打印日志可以得到如下結果:
從上圖可以看出服務已經注冊成功
④ 同時通過 Dubbo Admin 管理控制台也可以看到剛注冊的服務:
3.4 暴露遠程服務
① 在 demo-remote 層的 pom 文件中添加 distributionManagement 標簽並在其中配置 Nexus 私服的 snapshot 快照庫及 release 發布庫。
<distributionManagement>
<repository>
<id>yibao-releases</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>yibao-snapshots</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
② cd 到 demo-remote 目錄,執行 mvn deploy 命令打包,完成后可在 Nexus 私服看到剛打的依賴包。
③ 搭建一個測試項目並引入 demo-remote 依賴包,新建 TestController 類測試 Dubbo 接口。
注:該測試項目也需集成 Dubbo
package com.example.dawn.web.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.example.demo.remote.model.param.DemoParam;
import com.example.demo.remote.model.result.DemoDTO;
import com.example.demo.remote.service.RpcDemoService;
import com.yibao.dawn.web.annotation.LoginIgnore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author linjian
* @date 2019/3/7
*/
@RestController
@RequestMapping("test")
public class TestController {
@Reference(version = "1.0.0.dev")
private RpcDemoService rpcDemoService;
@GetMapping("dubbo")
public DemoDTO test() {
DemoParam param = new DemoParam();
param.setId(1);
return rpcDemoService.test(param);
}
}
③ 啟動測試項目,觀察 Dubbo Admin 管理控制台消費者一欄,可以看到測試項目已經作為一個消費者調用 RpcDemoService 接口類。
④ 訪問 http://localhost:8079/test/dubbo 查看接口返回結果。
四、結語
至此 Spring Boot 集成 Dubbo 的過程介紹完畢,我們通過一個簡易的 Dubbo 接口測試其可用性,下篇我們將介紹 HTTP 接口及 Dubbo 接口的一個重要編程規約 — 統一返回值
注:相關代碼已同步至 GitHub