Spring Boot 整合 Apache Dubbo
Apache Dubbo是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
注意,是
Apache Dubbo,不再是Alibaba Dubbo。简单来说就是Alibaba将Dubbo移交给Apache开源社区进行维护。参见 dubbo-spring-boot-project
Spring Boot 系列:整合 Alibaba Dubbo
一、本文示例说明
1.1 框架版本
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>
1.2 模块关系
- 根工程
order:管理工程信息; - 子工程
order-api:定义RPC服务的接口、参数以及响应结果的结果集; - 子工程
order-provider:RPC服务的提供端; - 子工程
order-consumer:RPC服务的消费端,实际开发过程中实际情况是其它服务的调用该订单RPC服务
二、根工程
2.1 创建项目 order
我这里为了和之前老版本的
alibaba的dubbo项目区分,文件名取为apache-dubbo-demo,maven项目名称为order。
该项目主要作用是定义工程信息、管理整个项目依赖版本等等,所以src目录不需要。
2.2 pom.xml
根工程中使用了<dependencyManagement>和<dependencies>进行依赖管理。
<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
3.1 项目依赖
无需更多依赖,所以很简单。
<?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>
3.2 封装 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;
}
}
- 先封装一个RPC 响应结果集
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 + '\'' +
'}';
}
}
3.3 编写一个 RPC 接口
public interface OrderDubboService {
RpcResult<OrderDomain> getOrder();
}
实体
OrderDomain.java挺简单的,详见Github仓库。
四、order-provider
此子项目是一个服务类项目,也就是将接口服务注册到zookeeper注册中心供消费端调取使用。
4.1 项目依赖
<?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>
4.2 服务实现接口
@Service
public class OrderDubboServiceImpl implements OrderDubboService {
@Override
public RpcResult<OrderDomain> getOrder() {
return RpcResult.success(new OrderDomain(1, 10086, LocalDateTime.now()));
}
}
注意:
@Service 是 dubbo 包下面的注解不是 Spring 里面的注解。
4.3 项目配置
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
此子项目就是一个消费项目,比如商品模块、财务模块等等。
5.1 项目依赖
<?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>
5.2 测试接口
模拟一个接口获取订单详情。
@RestController
@RequestMapping("/order")
public class OrderConsumerController {
@Reference
OrderDubboService orderDubboService;
@GetMapping("getOrder")
public RpcResult getOrder() {
return orderDubboService.getOrder();
}
}
注意:@Reference引入的是 Dubbo 接口,所以是 Dubbo 的注解。
5.3 配置文件
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 服务搭建成功。
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,成功返回数据如下:
{
"success":true,
"code":200,
"data":{
"id":1,
"orderNum":10086,
"gmtCreate":"2020-05-06T11:59:45.535"
},
"message":null
}
成功请求到 order-provider 提供的数据,说明 Dubbo 搭建成功!
七、总结
以上的完整代码我已上传到 Github,需要的可以自取测试,欢迎star!
文化交流
Spring Boot 整合 Apache Dubbo的更多相关文章
- Spring Boot 整合 Apache Ignite
关于Ignite的介绍,这边推荐三个链接进行学习了解. https://ignite.apache.org/,首选还是官网,不过是英文版,如果阅读比较吃力可以选择下方两个链接. https://www ...
- Spring Boot 整合 Dubbo和Zookeeper
Spring Boot 整合 Dubbo和Zookeeper Spring Boot 整合 Dubbo和Zookeeper 环境介绍 Zookeeper 安装 启动 Dubbo admin 搭建 创建 ...
- Spring Boot整合Dubbo使用及开发笔记
一.概述: Spring Dubbo是我开发的一个基于spring-boot和dubbo,目的是使用Spring boot的风格来使用dubbo.(即可以了解Spring boot的启动过程又可以学习 ...
- Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境: ...
- Spring Boot整合Dubbo2.x,解决其中遇到的坑
Dubbo了解 a high-performance, java based open source RPC framework. Dubbo官网 源码 文档 快速知道用法 本地服务 Spring 配 ...
- spring boot整合jsp的那些坑(spring boot 学习笔记之三)
Spring Boot 整合 Jsp 步骤: 1.新建一个spring boot项目 2.修改pom文件 <dependency> <groupId>or ...
- Spring Kafka和Spring Boot整合实现消息发送与消费简单案例
本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...
- spring boot整合Hadoop
最近需要用spring boot + mybatis整合hadoop,其中也有碰到一些坑,记录下来方便后面的人少走些弯路. 背景呢是因为需要在 web 中上传文件到 hdfs ,所以需要在spring ...
- (转)Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理
http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html 这篇文章我们来学习如何使用 Spring Boot 集成 A ...
随机推荐
- Java方法的重点
方法就是完成功能一个语句集合体 使用方法的原则:方法的原子性,一个方法只实现一个功能. 方法的重载 1.函数名必须相同 2.形参列表必须不同(可以是个数不同,类型不同,不然完全一样) 3.返回值可以相 ...
- 让ul li水平居中(任意删除li也能水平居中)
HTML代码: <div class="box"> <ul class="button-ct"> <li></li&g ...
- BJDCTF 2nd web
先贴一下Y1ng大佬的WP elementmaster 脑洞确实大,源码中hidden的id可以用hex解码成Po. 在URL后面输入Po.php得到一个点, 然后不知所措 被水淹没 实际上这里是要遍 ...
- Springboot:员工管理之环境准备(十(1))
1:静态资源 下载静态资源:https://files.cnblogs.com/files/applesnt/ztzy.zip 项目下载:https://files.cnblogs.com/files ...
- SpringBoot word 转换为 pdf
转换文件 swagger 地址, 基于 SpringBoot 开发 http://119.27.167.41:8888/convertor/swagger-ui.html 带有图片的word 转换体验 ...
- 二进制部署kubernetes集群_kube-apiserver提示"watch chan error: etcdserver: mvcc: required revision has been compacted'
查看kube-apiserver状态 [root@yxz-cluster01 ~]# systemctl status kube-apiserver -l ● kube-apiserver.servi ...
- Nacos - 阿里开源配置中心
配置中心相信大家都有听过,zookeeper.apollo等等都是配置中心的代表,但大部分都是JAVA系为主的,笔者主要开发语言使用的是Golang当然也有类似于ETCD这样的组件,但是并不方便管理也 ...
- pytorch Model Linear实现线性回归CUDA版本
实验代码 import torch import torch.nn as nn #y = wx + b class MyModel(nn.Module): def __init__(self): su ...
- Jmeter系列(7)- 基础线程组Thread Group
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html Thread Group基础线程组介绍 ...
- 关于宝塔下的项目中的php不能访问的问题
遇到的问题是访问项目根目录的所有php文件都是报404错,而其他文件则可以,比如txt,最后查资料发现 在宝塔运行网站的时候会在项目的根目录自动生成一个.user.ini文件,这个文件主要是防止对指定 ...