目录
- Dubbo
- RPC
- 什么是RPC
- Dubbo简介
- Dubbo 的架构
- 支持的协议
- Dubbo案例学习
- 本地直连方式
- **服务接口模块**
- **服务提供方**
- **服务消费方**
- **测试**
- Dubbo+Nacos
- **服务公共接口**
- **服务提供方**
- **服务消费方**
- **测试**
Dubbo
RPC
什么是RPC
RPC是远程过程调用(Remote Procedure Call)的缩写形式。是一种进程间的通信方式,是一种技术思想,而不是一种规范。在如今微服务火热的时代,进场需要在不同异地的服务需要互相调用,而RPC可以允许程序调用另一个地址空间(在不同服务器的服务)的过程或函数,而不用程序员去显示的编写远程调用的代码。意思即是说:无论是调用本地的方法,还是需要远程调用其他服务的方法,所需要编写的代码本质是相同的。
RPC远程调用过程示例:
RPC框架:Dubbo
、gRPC、Thrift、HSF
RPC最核心的内容:序列化和网络通信
Dubbo简介
Dubbo是一个分布式服务框架,拥有高性能和透明化的RPC远程服务调用方案以及SOA服务治理方案。
Dubbo 是阿里巴巴公司一个开源的高性能服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案,使得应用可通过高性能 RPC 实现服务的输出、输入功能和 Spring 框架无缝集成。
其核心部分包含:
-
远程通讯
: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。 -
集群容错
: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。 -
自动发现
: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
Dubbo 的架构
步骤:
- start:容器启动,将消费服务方加载进容器。
- register:消费服务方向注册中心注册自己的服务。
- subscribe:消费服务方向注册中心订阅自己所需要的服务。
- notify:注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- invoke:服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- count:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
支持的协议
dubbo、hession、rmi、http、webservice、thrift、memcached,redis。
dubbo官方推荐使用dubbo。dubbo的默认端口是20880。
因此,配置文件:
<dubbo:protocol name="dubbo" port="20880"/>
Dubbo案例学习
本地直连方式
直连模式:无注册中心,无监控,快速测试Dubbo的效果。
所需要的依赖:springboot(2.4.0)+Dubbo(2.7.1)
一共需要三个模块:
- 服务接口模块:对外暴漏的服务接口(消费方与提供方都需要),pojo对象。
- 服务提供方:提供方法的一方
- 服务消费方:使用方法的一方
服务接口模块
- pom.xml:所需要的依赖
<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>
<!--引入dubbo相关的依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.1</version>
</dependency>
- pojo:实现序列化
public class Student implements Serializable {
private Integer id;
private String name;
//getset,toString, 构造方法省略
}
- service
public interface StudentService {
public Student findAStudent();
}
服务提供方
- pom.xml:导入api(共同方法模块)依赖
<!--引入api的依赖-->
<dependency>
<groupId>com.sixu</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 配置文件:配置提供方端口号以及Dubbo相关配置
server.port=8081
#指定注册中心 N/A表示没有注册中心
dubbo.registry.address=N/A
dubbo.application.name=provider
# 扫描带有@Service(指Dubbo的)的包
dubbo.scan.base-packages=com.sixu.provider.service.impl
- 启动类,添加
@EnableDubboConfig
@SpringBootApplication
@EnableDubboConfig
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
- service层的impl
注意:类上有两个
@service注解
其中一个是将这个类的Bean对象注入容器,属于Srping的,标注业务层的。
另一个属于Dubbo,作用是用来标注这是服务提供方。
@Service //spring的
@org.springframework.stereotype.Service("studentService") //dubbo的
public class StudentServiceImpl implements StudentService {
@Override
public Student findAStudent() {
return new Student(001,"sixu"); //模拟从数据库中查询
}
}
服务消费方
- pom.xml:与服务方相同,导入api(共同方法模块)依赖
- 配置文件
server.port=8082
dubbo.application.name=consumer
- 启动类上标注
@EnableDubboConfig
注解 - controller层
@RestController
public class StudentController {
@Reference(url = "dubbo://localhost:20880") //因为是本地直连,所以服务方有固定的地址,dubbo默认端口为20880.
private StudentService studentService;
@GetMapping("findAStudent")
public String findAStudent(){
return studentService.findAStudent().toString();
}
}
测试
在网址上输入消费方的地址
Dubbo+Nacos
踩过的坑:我第一次做这个案例时,Dubbo的启动器以及dubbo-registry-nacos使用的版本都是2.7.1,但是启动项目时会报错。
No such extension com.alibaba.dubbo.registry.RegistryFactory by name nacos
然后我将版本都换成2.7.5,就正常启动了。
本次案例使用nacos作为注册中心,没有监控模块。
所以需要学习Nacos:
**案例结构:**与本地直连案例
一样,3个模块。
服务公共接口
结构与本地直连案例
的服务接口模块相同
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--引入dubbo相关的依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
<!--引入Nacos依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.0.0</version>
</dependency>
- pojo(相同)
- service(相同)
服务提供方
- pom.xml
<!--引入公共接口模块-->
<dependency>
<groupId>com.sixu</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 配置文件:application.yml
server:
port: 8081
dubbo:
# 配置服务信息
application:
name: provider
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
# 配置注册中心
registry:
address: nacos://127.0.0.1:8848
# 设置协议-协议由提供方指定消费方被动接受
protocol:
name: dubbo
port: 20880
#扫描有@service注解的包
scan:
base-packages: com.sixu.provider.service.impl
spring:
main:
# 解决Bean重复定义问题
allow-bean-definition-overriding: true
- 启动类,添加
@EnableDubboConfig
。 - service层的impl(相同)
服务消费方
- pom.xml
<!--引入公共接口模块-->
<dependency>
<groupId>com.sixu</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 配置文件:application.yml
server:
port: 8080
dubbo:
# 配置服务信息
application:
name: consumer
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
# 配置注册中心
registry:
address: nacos://127.0.0.1:8848
# 设置超时时间
consumer:
timeout: 4000
spring:
main:
# 解决Bean重复定义问题
allow-bean-definition-overriding: true
- 启动类上标注
@EnableDubboConfig
注解 - controller层
@RestController
public class StudentController {
@Reference
private StudentService studentService;
@GetMapping("findAStudent")
public String findAStudent(){
return studentService.findAStudent().toString();
}
}
测试
- 首先启动Nacos
- 依次启动提供方和消费方。
则提供方和消费方都被注册进注册中心。 - 测试结果: