目录
- 💌 所属专栏:【Dubbo3】
- 😀 作 者:长安不及十里
- 💻 工作:目前从事电力行业开发
- 🌈 目标:全栈开发
- 🚀 个人简介:一个正在努力学技术的Java工程师,专注基础和实战分享 ,欢迎咨询!
- 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘
- 参考资料:
- 参考课程
Dubbo3实战开发一套通:分布式微服务解决方案、全方位一网打尽|Nacos、gRPC、Triple、Consul、Zookeeper、SpringCloud_哔哩哔哩_bilibili
一 认识Dubbo
1.1 认识Dubbo
- 早期Dubbo的定位,基于JAVA的⾼性能,轻量级RPC框架 【high-performance, lightweight,Java-based RPC framework】,SOA【Service-Oriented Architecture ⾯向服务的架构】 = RPC+服务治理。
- 2018年阿⾥巴巴把这个框架捐献给了 Apache 基⾦会,正式更名为Apache Dubbo。
- 最新版本为Dubbo3.x,Apache Dubbo 是⼀款易⽤、⾼性能的 WEB 和 RPC 框架,同时为构建企业级微服务提供服务发现、流量治理、可观测、认证鉴权等能⼒、⼯具与最佳实践。
- Dubbo3 已在阿⾥巴巴内部微服务集群全⾯落地,成功取代运⾏多年的HSF 框架。依托于Dubbo3,阿⾥提出了⾃⼰的微服务解决⽅案DNS。
- 经过孵化,Dubbo⽬前成为Apache的顶级项⽬。
官⽅⽹站:
Apache Dubbo 中文
GitHub :
GitHub - apache/dubbo: The java implementation of Apache Dubbo. An RPC and microservice framework.
1.2 SOA与微服务
时⾄今⽇,SOA与微服务架构基本可以统⼀成⼀个概念了。
1.2.1 单体架构
特点:
- 单一部署单元: 整个应用作为一个单一的单元进行部署。
- 紧密耦合: 所有组件和模块紧密结合在一起,共享同一个代码库和数据存储。
- 开发简单: 初期开发相对简单,因为所有功能都在一个应用中。
- 易于理解和维护: 由于应用结构相对简单,因此更容易理解和维护。
优点:
- 开发简单快速: 初始阶段开发速度快,因为所有组件都在一个代码库中。
- 部署容易: 部署简单,只需将整个应用程序部署到服务器即可。
- 易于调试: 整体代码在一处,调试相对容易。
缺点:
- 扩展困难: 随着应用规模增长,单体架构难以扩展,可能导致性能问题。
- 复杂性增加: 随着时间推移,单体应用的代码库会变得庞大复杂,难以维护和理解。
- 技术选型受限: 难以采用新技术,因为整个应用程序需要统一的技术栈。
- 团队协作挑战: 大团队协作时,多人修改同一个代码库可能导致冲突。
1.2.2 水平扩展
特点:
- 增加实例数量: 水平扩展通过增加相同资源实例的数量来处理更多的负载。
- 分布式架构: 资源实例分布在多个节点或服务器上,共同处理请求。
- 弹性和伸缩性: 可根据需求动态地增加或减少实例数量,以应对流量波动。
- 平行处理能力: 实例并行处理请求,提高系统整体的吞吐量和性能。
优点:
- 高可用性: 分布在多个实例上,当一个实例出现故障时,其他实例可以继续提供服务,提高系统的可用性。
- 扩展性: 可根据需求快速地扩展系统能力,应对增加的负载。
- 性能提升: 增加实例可以提高系统整体的并发处理能力,提升性能表现。
缺点:
- 数据一致性: 在分布式环境下,确保数据一致性可能变得更加复杂。
- 部署和管理复杂性: 管理大量的实例可能会增加部署和监控的复杂性。
- 成本增加: 增加实例数量可能会导致资源成本的增加,特别是在负载低时,维护多个实例可能造成资源浪费。
1.2.3 垂直扩展
特点:
- 单一节点增强: 垂直扩展是在单个节点上增加资源,而不是增加多个节点。
- 相对简单: 相对于水平扩展(添加更多的节点),垂直扩展通常更为直接和简单。
优点:
- 易于管理: 管理一个大节点比管理多个节点更简单。
- 适用性广泛: 对于一些应用来说,垂直扩展是更经济的解决方案,尤其是在资源需求不是线性增长的情况下。
- 性能提升明显: 增加单个节点的资源可以显著提高性能,尤其是对于需要大量内存或处理能力的应用。
缺点:
- 硬件限制: 有物理限制,不能无限制地增加资源,达到某个点后无法再进行扩展。
- 单点故障: 如果垂直扩展后的节点发生故障,系统可能会完全失效,而水平扩展可以通过其他节点来保持系统的可用性。
- 成本高昂: 在某些情况下,购买更高规格的硬件可能比增加多个普通规格的硬件更昂贵。
1.2.4 RPC架构[Remote Procedure CaLL]
特点:
- 封装远程调用: 允许程序像调用本地函数一样调用远程服务,隐藏了底层的网络通信细节。
- 跨语言支持: 可以支持不同编程语言之间的通信,使得异构系统能够相互调用。
- 支持不同协议: 可以使用多种协议,如HTTP、TCP等,来进行远程调用。
- 提供接口定义: 常常会使用IDL(接口定义语言)来定义服务接口,使得不同系统可以基于相同的接口进行交互。
优点:
- 抽象复杂性: 隐藏了网络通信的细节,使得远程调用看起来像本地调用,降低了开发者的复杂性。
- 模块化和分布式: 允许系统模块化部署,让不同模块能够分布在不同的服务器上,提高系统的灵活性和可伸缩性。
- 易于扩展: 可以方便地添加新的远程服务,而不需要修改现有系统的架构。
缺点:
- 性能开销: 额外的序列化、网络传输和反序列化会增加一定的性能开销。
- 网络故障: 如果网络出现故障,会导致远程调用失败,需要实施容错机制以应对这种情况。
- 调试困难: 由于远程调用隐藏了底层细节,调试时可能难以追踪问题。
1.2.5 SOA架构[Service-Oriented Architecture]
SOA架构是RPC架构的演化。代表框架Dubbo
- RPC 架构的问题
- SOA 架构
- 服务总线
SOA(面向服务的架构)是一种设计方法,将软件系统划分为多个独立的、可重用的服务,这些服务通过标准化的接口进行通信和交互。
特点:
- 服务独立性: 服务是独立的功能单元,可以被独立开发、部署和升级。
- 松耦合: 服务之间通过定义良好的接口进行通信,使得系统模块之间的耦合度降低。
- 服务重用: 可以在不同的应用程序中重用服务,提高了开发效率和系统的灵活性。
- 标准化接口: 服务之间通常使用标准化的接口进行通信,如SOAP、REST等。
优点:
- 灵活性和可扩展性: SOA允许系统灵活地添加、移除或更改服务,以适应业务需求的变化。
- 跨平台和跨语言: 可以实现不同平台和不同语言之间的互操作性,增强了系统的整合性。
- 提高组织效率: 可以提高开发团队的效率,因为可以复用现有的服务,而不必重复开发相同的功能。
缺点:
- 复杂性: 将系统拆分为多个服务,需要良好的设计和管理,增加了系统的复杂性。
- 性能问题: 服务间通信可能引入额外的网络开销和延迟,需要考虑性能问题。
- 安全性隐患: 分布式的特性可能会增加安全风险,需要考虑对服务的安全性进行有效管理。
1.2.6 微服务架构
微服务是SOA架构的升级,在微服务体系统中,没有⼦系统了,全部都是服务化功能。微服务架构代表框架,SpringCloud, DNS(Dubbo+Nacos+Sentinel)
微服务架构是一种软件架构模式,将应用程序设计为一组小型、自治的服务单元,每个服务专注于完成特定的业务功能。这些服务可以独立开发、部署、扩展和管理,通过轻量级通信机制(如HTTP或消息队列)相互协作,共同构建一个大型复杂的应用系统。
特点:
- 服务拆分: 将应用程序拆分成多个小型服务,每个服务都有自己的数据存储、业务逻辑和用户界面。
- 自治性: 每个服务都是自治的,可以独立部署和扩展,服务之间通过明确定义的接口进行通信。
- 分布式和去中心化: 微服务架构支持分布式部署,没有单点故障,并且可以根据需求选择不同的技术栈。
- 弹性和可伸缩性: 可以根据需求对单个服务进行水平或垂直扩展,以应对负载变化。
- 技术多样性: 不同服务可以使用不同的编程语言、框架和技术栈,使得团队可以选择最适合其需求的工具。
优点:
- 灵活性和可维护性: 小型服务更易于理解、开发和维护,有利于团队协作和快速迭代。
- 高可用性和容错性: 分布式架构使系统更加鲁棒,单个服务故障不会影响整个系统。
- 扩展性: 可以根据需求对单个服务进行独立扩展,而无需整体扩展整个应用。
- 技术栈灵活性: 不同服务可以使用最适合其需求的技术,提高了开发效率和系统灵活性。
挑战:
- 复杂性: 微服务架构引入了分布式系统的复杂性,包括服务间通信、一致性、监控和部署等方面的挑战。
- 分布式事务: 多个服务之间的事务管理可能更为复杂,需要仔细设计和实施。
- 部署和监控: 需要有效的部署管道和监控系统来确保服务的可靠性和稳定性。
- 团队组织: 需要良好的团队组织和沟通机制,以便不同团队协作开发和维护各自的服务。
1.3 Dubbo3 升级点
● **易⽤性 **
开箱即⽤易⽤性⾼,如 Java 版本的⾯向接⼝代理特性能实现本地透明调⽤功能丰富,基于原⽣库或轻量扩展即可实现绝⼤多数的微服务治理能⼒。更加完善了多语⾔⽀持(GO PYTHON RUST)
● 超⼤规模微服务实践 **
○ ⾼性能通信(Triple GRPC)
○ ⾼可扩展性 (SPI 多种序列化⽅式 多种协议)
○ 丰富的服务治理能⼒
○ 超⼤规模集群实例⽔平扩展
● 云原⽣ **
○ 容器调度平台(Kubernetes)
将服务的组织与注册交给底层容器平台,如 Kubernetes,这是更云原⽣的⽅式。
○ Service Mesh
原有Mesh结构中通过Sidecar完成负载均衡、路由等操作,但是存在链路的性能损耗⼤,现有系统迁移繁琐等问题。 Dubbo3 引⼊Proxyless Mesh,直接和I控制⾯交互[istio]通信。集成ServiceMesh更为⽅便,效率更⾼。
1.4 谁在参与建设、使⽤Dubbo3
阿⾥巴巴【电商系统的考拉、交易平台,饿了么、钉钉】、携程、⼯商银⾏、中 国⼈寿、海尔、⾦蝶、⽃⻥、⼩⽶、京东…
二 第⼀个Dubbo程序开发
2.1 专业术语
- provider 功能提供者
- consumer 功能调⽤者【功能消费者】
- commons-api 通⽤内容 entity service接⼝
- registry 注册中⼼ 1. 可选 2. ⽤于管理provider集群
2.2 JDK 与 Dubbo版本对应问题说明
- JDK8 与 Dubbo3.1.x以前的版本匹配,在使⽤Zookeeper注册作为注册中
⼼时,消费者会出现节点已经存在的异常https://github.com/apache/dubbo/issues/11077 - JDK17 与 Dubbo3.1.x之前的版本搭配使⽤会出现如下问题
a. JDK9之后的深反射问题,需要通过JVM参数配置解决
-Dio.netty.tryReflectionSetAccessible=true
--add-opens
java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens
java.base/java.nio=ALL-UNNAMED
--add-opens
java.base/java.lang=ALL-UNNAMED
b. Dubbo3.2.0.beat4以前的版本使⽤的是Spring5.2.x 不能⽀持 JDK17
会产⽣如下异常,Unsupported class file major version 61 【major 61 对应 17 】
版本需要升级到Dubbo3.2.0.beat5以上版本
2.3 SpringMvc整合Dubbo3
- 结构
- 父依赖
<?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.shu</groupId>
<artifactId>SpringMvc-Dubbo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>Dubbo-Provider</module>
<module>Dubbo-Consumer</module>
<module>Dubbo-Api</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
</project>
- 先建公共Api
- 先建接口
package com.shu.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
/**
* @author : EasonShu
* @date : 2023/11/19 12:34
* @Version: 1.0
* @Desc : 用户实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User implements Serializable {
private String name;
private String password;
private String email;
private String phone;
}
package com.shu.service;
import com.shu.model.User;
/**
* @author : EasonShu
* @date : 2023/11/19 12:35
* @Version: 1.0
* @Desc : 用户服务接口
*/
public interface UserService {
// 通过用户名查询用户信息
User queryUserByName(String name);
// 保存用户信息
void saveUser(User user);
}
- 新建服务提供者
引入公共依赖
<dependency>
<groupId>com.shu</groupId>
<artifactId>Dubbo-Api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
编写服务接口实现类
package com.shu.service;
import com.shu.model.User;
import com.sun.istack.internal.NotNull;
import lombok.extern.slf4j.Slf4j;
/**
* @author : EasonShu
* @date : 2023/11/19 12:37
* @Version: 1.0
* @Desc :
*/
@Slf4j
public class UserServiceProvider implements UserService{
@Override
public User queryUserByName(String name) {
log.info("查询用户信息成功");
return new User("EasonShu", "123456", "[email protected]", "177134e59165");
}
@Override
public void saveUser(@NotNull User user) {
log.info("保存用户信息成功");
log.info("用户信息为:{}", user.toString());
}
}
编写SpringMvc配置文件:applicationContext-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="DubbuoProvider"/>
<dubbo:protocol name="dubbo" port="-1" />
<bean id="UserService" class="com.shu.service.UserServiceProvider"/>
<dubbo:service interface="com.shu.service.UserService" ref="UserService"/>
</beans>
编写启动类
package com.shu;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.CountDownLatch;
/**
* @author : EasonShu
* @date : 2023/11/19 12:40
* @Version: 1.0
* @Desc : Dubbo服务提供者启动类
*/
@EnableDubbo
public class DubboProviderApplication {
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-provider.xml");
applicationContext.start();
new CountDownLatch(1).await();
}
}
观察启动日志:ip信息 Dubbo Application1.1 is ready., dubbo version: 3.2.0, current host: 192.168.2.35
- 编写消费者
编写配置文件:applicationContext-consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="Dubbo-consuemer">
<dubbo:parameter key="qos.enable" value="false"/>
</dubbo:application>
<dubbo:reference interface="com.shu.service.UserService" id="UserService"
url="dubbo://192.168.2.35:20880/com.shu.service.UserService"/>
</beans>
注意qos:
ERROR org.apache.dubbo.qos.server.Server
Address already in use
**问题产⽣的原因: **
Qos=Quality of Service,qos是Dubbo的在线运维命令,可以对服务进⾏动态的配置、控制及查询, Dubboo2.5.8新版本重构了telnet(telnet是从 Dubbo2.0.5开始⽀持的)模块,提供了新的telnet命令⽀ 持,新 版本的telnet端⼝与dubbo协议的端⼝是不同的端⼝, 默认为22222。正是因为这个问题:如果在⼀台服务器 ⾥⾯,启动provider时22222端⼝,⽽consumer启动
时就会报错了。
解决方案
xml
<dubbo:parameter key="qos.enable" value="true"/> <!--
是否开启在线运维命令 -->
<dubbo:parameter key="qos.accept.foreign.ip" value="false"/> <!--
不允许其他机器的访问 -->
<dubbo:parameter key="qos.port" value="33333"/> <!--
修改port-->
yaml
dubbo.application.qos.enable=true
dubbo.application.qos.port=33333
dubbo.application.qos.accept.foreign.ip=false
- 编写启动类
package com.shu.service;
import com.shu.model.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* @author : EasonShu
* @date : 2023/11/19 12:52
* @Version: 1.0
* @Desc :
*/
public class DubboConsumerApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-consumer.xml");
UserService userService = applicationContext.getBean(UserService.class);
System.out.println(userService.queryUserByName("EasonShu"));
userService.saveUser(new User("小米","123456", "", ""));
System.in.read();
}
}
- 启动测试
- 补充
provider基于dubbo协议 默认的端⼝是20880
<dubbo:protocol name="dubbo" port="20880"/>
但是随着应⽤数量过⼤如果显示指定协议端⼝,会容易造成端⼝冲突所以建议按照如下写法设置
端⼝
<dubbo:protocol name="dubbo" port="-1"/>
- 过程解析:(通信方式,协议,序列化)
2.4 SpringBoot 与Dubbo3整
深度封装,把公⽤的配置放置到application.yml中,把个性的配置应⽤注解进⾏设置
- 结构
- 服务者依赖
<?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.7.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shu</groupId>
<artifactId>Dubbo-Provider-Boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Dubbo-Provider-Boot</name>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>com.shu</groupId>
<artifactId>Dubbo-Api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 配置文件
spring:
application:
name: DUBBO-PROVIDER-BOOT
dubbo:
protocol:
name: dubbo
port: -1
- 编写代码
package com.shu.service;
import com.shu.model.User;
import com.sun.istack.internal.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
/**
* @author : EasonShu
* @date : 2023/11/19 12:37
* @Version: 1.0
* @Desc : Dubbo服务提供者
*/
@Slf4j
@Service
@DubboService
public class UserServiceProvider implements UserService{
@Override
public User queryUserByName(String name) {
log.info("查询用户信息成功");
return new User("EasonShu", "123456", "[email protected]", "177134e59165");
}
@Override
public void saveUser(@NotNull User user) {
log.info("保存用户信息成功");
log.info("用户信息为:{}", user.toString());
}
}
- 启动类
package com.shu;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.CountDownLatch;
/**
* @author : EasonShu
* @date : 2023/11/19 12:40
* @Version: 1.0
* @Desc : Dubbo服务提供者启动类
*/
@EnableDubbo
@SpringBootApplication
public class DubboProviderApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(DubboProviderApplication.class, args);
}
}
- 观察启动结果
- 编写消费者依赖
<?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.7.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shu</groupId>
<artifactId>Dubbo-Consumer-Boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>>Dubbo-Consumer-Boot</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>com.shu</groupId>
<artifactId>Dubbo-Api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 配置文件
spring:
application:
name: DUBBO-CONSUMER-BOOT
dubbo:
application:
qos-enable: false
- 启动类
package com.shu;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author : EasonShu
* @date : 2023/11/19 14:28
* @Version: 1.0
* @Desc :
*/
@SpringBootApplication
@EnableDubbo
public class DubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}
}
- 测试类
package com.shu;
import com.shu.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author : EasonShu
* @date : 2023/11/19 14:29
* @Version: 1.0
* @Desc :
*/
@SpringBootTest
public class DubboConsumerApplicationTest {
@DubboReference(url = "dubbo://192.168.2.35:20880/com.shu.service.UserService")
private UserService userService;
@Test
public void test() {
System.out.println(userService.queryUserByName("EasonShu"));
}
@Test
public void test1() {
userService.saveUser(null);
}
}
- 结果
2.5 细节分析
@EnableDubbo注解的作⽤
- @EnableDubbo ⽤于扫描@DubboService 并把对应的对象实例
化,发布成RPC服务。
扫描的路径:应⽤这个注解的类(启动类)所在的包及其⼦包。 - 如果@DubboService注解修饰的类没有放到@EnableDubbo注解
修饰类当前包及其⼦包,还希望能够扫描到它该如何处理?
可以通过[@DubboComponentScan(basePackages ](/DubboComponentScan(basePackages ) =
{“org.suns.service”}),显示的指定扫描的路径 - yml进⾏配置扫描@DubboService 并把对应的对象实例化,发布
成RPC服务。
dubbo.scan.base-packages 等同于 @EnableDubbo
@DubboService注解的作⽤
- 应⽤@DubboService注解修饰类型,SpringBoot会创建这个类型
的对象,并发布成Dubbo服务。 - @DubboService 等同于 @Component(@Service) ) @Bean注解的
创建对象的作⽤。
通过源码SingletonObjects可以验证 - @DubboService
a. 创建对象 等同于 @Component(@Service) ) @Bean
b. 发布成RPC服务 - 后续开发过程中如果考虑兼容性,建议实现类不仅仅要加⼊
@DubboService注解,同时也要加⼊@Service注解
@DubboReference注解的作⽤
- 在Consumer端,通过@DubboReference,注⼊远端服务的代理
对象。 - @DubboReference类似于原始Spring开发中@Autowired注解的
作⽤。