经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
Spring Boot 整合 Apache Dubbo的示例代码
来源:jb51  时间:2021/7/5 8:33:43  对本文有异议

Apache Dubbo是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

注意,是 Apache Dubbo,不再是 Alibaba Dubbo。简单来说就是 AlibabaDubbo 移交给 Apache 开源社区进行维护。参见 dubbo-spring-boot-project

Spring Boot 系列:整合 Alibaba Dubbo

一、本文示例说明

1.1 框架版本Dubbo 版本

  1. <dependency>
  2. <groupId>org.apache.dubbo</groupId>
  3. <artifactId>dubbo-spring-boot-starter</artifactId>
  4. <version>2.7.5</version>
  5. </dependency>

Spring Boot 版本

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.1.1.RELEASE</version>
  5. <relativePath/>
  6. </parent>

1.2 模块关系

  • 根工程 order:管理工程信息;
  • 子工程 order-api:定义RPC服务的接口、参数以及响应结果的结果集;
  • 子工程 order-providerRPC服务的提供端;
  • 子工程 order-consumerRPC服务的消费端,实际开发过程中实际情况是其它服务的调用该订单RPC服务

二、根工程

2.1 创建项目 order

我这里为了和之前老版本的alibabadubbo项目区分,文件名取为apache-dubbo-demomaven 项目名称为order

该项目主要作用是定义工程信息、管理整个项目依赖版本等等,所以src目录不需要。

2.2 pom.xml

根工程中使用了<dependencyManagement><dependencies>进行依赖管理。

<dependencyManagement>:声明全局依赖,当子项目指定引用才会继承依赖;<dependencies>:声明全局依赖,子项目直接自动继承依赖。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <!-- 父级引用 -->
  8. <parent>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-parent</artifactId>
  11. <version>2.1.1.RELEASE</version>
  12. <relativePath/>
  13. </parent>
  14.  
  15. <!-- 基本信息 -->
  16. <groupId>cn.van.order</groupId>
  17. <artifactId>order</artifactId>
  18. <version>1.0.0-SNAPSHOT</version>
  19. <name>${project.artifactId}</name>
  20. <description>Apache Dubbo 根项目</description>
  21.  
  22. <!--配置-->
  23. <properties>
  24. <java.version>1.8</java.version>
  25. <dubbo.version>2.7.5</dubbo.version>
  26. <zookeeper.version>3.4.14</zookeeper.version>
  27. </properties>
  28.  
  29. <!-- 子项目 -->
  30. <modules>
  31. <module>order-api</module>
  32. <module>order-provider</module>
  33. <module>order-consumer</module>
  34. </modules>
  35.  
  36. <!--声明全局依赖(子项目需要显示的引用才会继承依赖)-->
  37. <dependencyManagement>
  38. <dependencies>
  39. <!-- dubbo-start依赖 -->
  40. <dependency>
  41. <groupId>org.apache.dubbo</groupId>
  42. <artifactId>dubbo-spring-boot-starter</artifactId>
  43. <version>${dubbo.version}</version>
  44. </dependency>
  45. <!--zookeeper 注册中心客户端引入 使用的是curator客户端 -->
  46. <dependency>
  47. <groupId>org.apache.dubbo</groupId>
  48. <artifactId>dubbo-dependencies-zookeeper</artifactId>
  49. <version>${dubbo.version}</version>
  50. <type>pom</type>
  51. <exclusions>
  52. <exclusion>
  53. <artifactId>slf4j-log4j12</artifactId>
  54. <groupId>org.slf4j</groupId>
  55. </exclusion>
  56. </exclusions>
  57. </dependency>
  58. </dependencies>
  59. </dependencyManagement>
  60.  
  61. <!--声明全局依赖(子项目不需要显示的引用,自动继承依赖)-->
  62. <dependencies>
  63. <!-- spring boot 依赖 -->
  64. <dependency>
  65. <groupId>org.springframework.boot</groupId>
  66. <artifactId>spring-boot-starter</artifactId>
  67. </dependency>
  68. <dependency>
  69. <groupId>org.springframework.boot</groupId>
  70. <artifactId>spring-boot-starter-test</artifactId>
  71. <scope>test</scope>
  72. <exclusions>
  73. <exclusion>
  74. <groupId>org.junit.vintage</groupId>
  75. <artifactId>junit-vintage-engine</artifactId>
  76. </exclusion>
  77. </exclusions>
  78. </dependency>
  79. </dependencies>
  80.  
  81. <!-- 打包插件 -->
  82. <build>
  83. <plugins>
  84. <plugin>
  85. <groupId>org.springframework.boot</groupId>
  86. <artifactId>spring-boot-maven-plugin</artifactId>
  87. </plugin>
  88. </plugins>
  89. </build>
  90. </project>

三、order-api

3.1 项目依赖

无需更多依赖,所以很简单。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <parent>
  8. <groupId>cn.van.order</groupId>
  9. <artifactId>order</artifactId>
  10. <version>1.0.0-SNAPSHOT</version>
  11. </parent>
  12.  
  13. <groupId>cn.van.order</groupId>
  14. <artifactId>order-api</artifactId>
  15. <version>1.0.0-SNAPSHOT</version>
  16. <name>${project.artifactId}</name>
  17. <description>dubbo公共项目</description>
  18.  
  19.  
  20. <build>
  21. <plugins>
  22. <plugin>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-maven-plugin</artifactId>
  25. </plugin>
  26. </plugins>
  27. </build>
  28.  
  29. </project>

3.2 封装 RPC 结果集先封装一个返回码枚举类ResultCodeEnum.java

  1. public enum ResultCodeEnum {
  2. /*** 通用部分 100 - 599***/
  3. // 成功请求
  4. SUCCESS(200, "successful"),
  5. /*** 这里可以根据不同模块用不同的区级分开错误码,例如: ***/
  6.  
  7. // 1000~1999 区间表示用户模块错误
  8. // 2000~2999 区间表示订单模块错误
  9. // 3000~3999 区间表示商品模块错误
  10. // 。。。
  11.  
  12. ORDER_NOT_FOUND(2000, "order not found"),
  13. ;
  14. /**
  15. * 响应状态码
  16. */
  17. private Integer code;
  18. /**
  19. * 响应信息
  20. */
  21. private String message;
  22.  
  23. ResultCodeEnum(Integer code, String msg) {
  24. this.code = code;
  25. this.message = msg;
  26. }
  27.  
  28. public Integer getCode() {
  29. return code;
  30. }
  31.  
  32. public String getMessage() {
  33. return message;
  34. }
  35.  
  36. public void setMessage(String message) {
  37. this.message = message;
  38. }
  39. }

先封装一个RPC 响应结果集RpcResult.java

  1. public class RpcResult <T> implements Serializable {
  2.  
  3. /**
  4. * 是否响应成功
  5. */
  6. private Boolean success;
  7. /**
  8. * 响应状态码
  9. */
  10. private Integer code;
  11. /**
  12. * 响应数据
  13. */
  14. private T data;
  15. /**
  16. * 错误信息
  17. */
  18. private String message;
  19.  
  20. // 构造器开始
  21. /**
  22. * 无参构造器(构造器私有,外部不可以直接创建)
  23. */
  24. private RpcResult() {
  25. this.code = 200;
  26. this.success = true;
  27. }
  28. /**
  29. * 有参构造器
  30. * @param obj
  31. */
  32. private RpcResult(T obj) {
  33. this.code = 200;
  34. this.data = obj;
  35. this.success = true;
  36. }
  37.  
  38. /**
  39. * 有参构造器
  40. * @param resultCode
  41. */
  42. private RpcResult(ResultCodeEnum resultCode) {
  43. this.success = false;
  44. this.code = resultCode.getCode();
  45. this.message = resultCode.getMessage();
  46. }
  47. // 构造器结束
  48.  
  49. /**
  50. * 通用返回成功(没有返回结果)
  51. * @param <T>
  52. * @return
  53. */
  54. public static<T> RpcResult<T> success(){
  55. return new RpcResult();
  56. }
  57.  
  58. /**
  59. * 返回成功(有返回结果)
  60. * @param data
  61. * @param <T>
  62. * @return
  63. */
  64. public static<T> RpcResult<T> success(T data){
  65. return new RpcResult<T>(data);
  66. }
  67.  
  68. /**
  69. * 通用返回失败
  70. * @param resultCode
  71. * @param <T>
  72. * @return
  73. */
  74. public static<T> RpcResult<T> failure(ResultCodeEnum resultCode){
  75. return new RpcResult<T>(resultCode);
  76. }
  77.  
  78. public Boolean getSuccess() {
  79. return success;
  80. }
  81.  
  82. public void setSuccess(Boolean success) {
  83. this.success = success;
  84. }
  85.  
  86. public Integer getCode() {
  87. return code;
  88. }
  89.  
  90. public void setCode(Integer code) {
  91. this.code = code;
  92. }
  93.  
  94. public T getData() {
  95. return data;
  96. }
  97.  
  98. public void setData(T data) {
  99. this.data = data;
  100. }
  101.  
  102. public String getMessage() {
  103. return message;
  104. }
  105.  
  106. public void setMessage(String message) {
  107. this.message = message;
  108. }
  109.  
  110. @Override
  111. public String toString() {
  112. return "RpcResult{" +
  113. "success=" + success +
  114. ", code=" + code +
  115. ", data=" + data +
  116. ", message='" + message + '\'' +
  117. '}';
  118. }
  119. }

3.3 编写一个 RPC 接口

  1. public interface OrderDubboService {
  2. RpcResult<OrderDomain> getOrder();
  3. }

实体OrderDomain.java挺简单的,详见 Github 仓库。

四、order-provider

此子项目是一个服务类项目,也就是将接口服务注册到zookeeper注册中心供消费端调取使用。

4.1 项目依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <parent>
  7. <groupId>cn.van.order</groupId>
  8. <artifactId>order</artifactId>
  9. <version>1.0.0-SNAPSHOT</version>
  10. </parent>
  11.  
  12. <groupId>cn.van.order</groupId>
  13. <artifactId>order-provider</artifactId>
  14. <version>1.0-SNAPSHOT</version>
  15. <name>${project.artifactId}</name>
  16. <description>Dubbo 服务提供者</description>
  17.  
  18. <dependencies>
  19. <dependency>
  20. <groupId>cn.van.order</groupId>
  21. <artifactId>order-api</artifactId>
  22. <version>1.0.0-SNAPSHOT</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.apache.dubbo</groupId>
  26. <artifactId>dubbo-spring-boot-starter</artifactId>
  27. </dependency>
  28. <!-- zookeeper依赖 -->
  29. <dependency>
  30. <groupId>org.apache.dubbo</groupId>
  31. <artifactId>dubbo-dependencies-zookeeper</artifactId>
  32. <version>${dubbo.version}</version>
  33. <type>pom</type>
  34. <exclusions>
  35. <exclusion>
  36. <artifactId>slf4j-log4j12</artifactId>
  37. <groupId>org.slf4j</groupId>
  38. </exclusion>
  39. </exclusions>
  40. </dependency>
  41. </dependencies>
  42.  
  43. <build>
  44. <plugins>
  45. <plugin>
  46. <groupId>org.springframework.boot</groupId>
  47. <artifactId>spring-boot-maven-plugin</artifactId>
  48. </plugin>
  49. </plugins>
  50. </build>
  51. </project>

4.2 服务实现接口

  1. @Service
  2. public class OrderDubboServiceImpl implements OrderDubboService {
  3. @Override
  4. public RpcResult<OrderDomain> getOrder() {
  5. return RpcResult.success(new OrderDomain(1, 10086, LocalDateTime.now()));
  6. }
  7. }

注意:
@Servicedubbo 包下面的注解不是 Spring 里面的注解。

4.3 项目配置

  • dubbo 的配置直接用 dubbo,不再以 Spring 开头;
  • base-packages:指定接口实现所在路径。
  1. server:
  2. # 服务端口
  3. port: 7777
  4. spring:
  5. application:
  6. name: order-provider
  7. # dubbo 相关配置(dubbo 的配置不再以 Spring 开头)
  8. dubbo:
  9. application:
  10. # 应用名称
  11. name: order-provider
  12. scan:
  13. # 接口实现者(服务实现)包
  14. base-packages: cn.van.order.service.impl
  15. # 注册中心信息
  16. registry:
  17. address: zookeeper://127.0.0.1:2181
  18. protocol:
  19. # 协议名称
  20. name: dubbo
  21. # 协议端口
  22. port: 20880

五、order-consumer

此子项目就是一个消费项目,比如商品模块、财务模块等等。

5.1 项目依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <parent>
  8. <groupId>cn.van.order</groupId>
  9. <artifactId>order</artifactId>
  10. <version>1.0.0-SNAPSHOT</version>
  11. </parent>
  12.  
  13. <groupId>cn.van.order</groupId>
  14. <artifactId>order-consumer</artifactId>
  15. <version>1.0-SNAPSHOT</version>
  16. <name>${project.artifactId}</name>
  17. <description>Dubbo 消费者</description>
  18.  
  19.  
  20. <dependencies>
  21. <dependency>
  22. <groupId>cn.van.order</groupId>
  23. <artifactId>order-api</artifactId>
  24. <version>1.0.0-SNAPSHOT</version>
  25. </dependency>
  26.  
  27. <!-- web项目依赖 -->
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-web</artifactId>
  31. </dependency>
  32.  
  33. <!-- dubbo依赖 -->
  34. <dependency>
  35. <groupId>org.apache.dubbo</groupId>
  36. <artifactId>dubbo-spring-boot-starter</artifactId>
  37. </dependency>
  38.  
  39. <!-- dubbo的zookeeper依赖 -->
  40. <dependency>
  41. <groupId>org.apache.dubbo</groupId>
  42. <artifactId>dubbo-dependencies-zookeeper</artifactId>
  43. <version>${dubbo.version}</version>
  44. <type>pom</type>
  45. <exclusions>
  46. <exclusion>
  47. <artifactId>slf4j-log4j12</artifactId>
  48. <groupId>org.slf4j</groupId>
  49. </exclusion>
  50. </exclusions>
  51. </dependency>
  52. </dependencies>
  53.  
  54. <build>
  55. <plugins>
  56. <plugin>
  57. <groupId>org.springframework.boot</groupId>
  58. <artifactId>spring-boot-maven-plugin</artifactId>
  59. </plugin>
  60. </plugins>
  61. </build>
  62. </project>

5.2 测试接口

模拟一个接口获取订单详情。

  1. @RestController
  2. @RequestMapping("/order")
  3. public class OrderConsumerController {
  4. @Reference
  5. OrderDubboService orderDubboService;
  6.  
  7. @GetMapping("getOrder")
  8. public RpcResult getOrder() {
  9. return orderDubboService.getOrder();
  10. }
  11. }

注意:@Reference引入的是 Dubbo 接口,所以是 Dubbo 的注解。

5.3 配置文件

  1. server:
  2. port: 7000
  3. spring:
  4. application:
  5. name: order-consumer
  6. # dubbo 相关配置
  7. dubbo:
  8. application:
  9. name: order-consumer
  10. registry:
  11. address: zookeeper://127.0.0.1:2181

六、测试

一切就绪,如果在order-consumer 的测试接口能成功请求到数据,则证明 Dubbo 服务搭建成功。

6.1 启动 zookeeper

我们选用zookeeper作为注册中心,因此启动项目之前需要先启动它。

6.2 dubbo-admin

dubbo-admin 便于观察 order-provider 是否成功将接口注册,具体安装步骤详见apache/dubbo-admin

默认端口:8080

6.3 启动 dubbo-provider

成功启动后可以在dubbo-admin:已经成功将接口 OrderService 注册到 zookeeper 上如下:

成功将借口注册到注册中心,说明dubbo-provider 注册成功。

6.4 启动 order-cosumer

启动消费者项目,在浏览器请求消费接口:http://localhost:7000/order/getOrder,成功返回数据如下:

  1. {
  2. "success":true,
  3. "code":200,
  4. "data":{
  5. "id":1,
  6. "orderNum":10086,
  7. "gmtCreate":"2020-05-06T11:59:45.535"
  8. },
  9. "message":null
  10. }

成功请求到 order-provider 提供的数据,说明 Dubbo 搭建成功!

七、总结

以上的完整代码我已上传到 Github,需要的可以自取测试,欢迎star

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号