Dubbo介绍与入门实战
前言
Dubbo作为一款RPC和微服务框架,还是很值得深入学习一波的。
Dubbo帮助我们解决了微服务实战中的两个问题:
1、作为服务开发框架,制定了微服务定义、开发与调用的规范;并通过RPC完成数据交换。解决了开发和通讯的问题。
2、抽象了一套微服务治理模式,包括地址发现、负载均衡、流量路由、可观测性。简化微服务的运维。
架构
总体架构
Provider:服务提供方
Consumer:服务消费方
Registry:服务注册与发现的注册中心
Monitor:监控中心,统计调用次数与时间
Container:服务运行容器
调用关系说明
0、服务容器启动,运行服务提供者。
1、服务提供者启动时,向注册中心注册自己。
2、服务消费者启动,从注册中心订阅自己所需的服务。
3、注册中心将服务提供者地址返回给服务消费者,包括变更。
4、服务消费者调用服务提供者
5、服务提供者与消费者,定期上报调用信息。
代码架构
说明:
1、左侧为服务消费使用的接口;右侧为服务提供方使用的接口;中轴线上为双方都使用到的接口。
2、紫色三角箭头为继承关系,其它标注参考图最上一排的文字。
各层说明
- Config 配置层:对外配置接口。
- Proxy 服务代理层:服务接口透明代理,生成客户端Stub和服务端Skeleton。
- Registry 注册中心层:封装服务地址的注册与发现,以服务URL为中心。
- Cluster 路由层:封装多个提供者的路由及负载均衡。
- Monitor 监控层:RPC调用次数与调用时间监控。
- Protocol 远程调用层:封装RPC调用。
- Exchange 信息交换层:封装请求响应模式,同步转异步,以Request、Response为中心。
- Transport 网络传输层:抽象mina和netty为统一接口,完成网络传输。
- Serialize 数据序列化层:能够进行复用的一些工具。
核心概念与功能
服务发现
Dubbo提供了服务发现的机制,依赖于第三方注册中心组件来协助。
常见的注册中心如 Nacos、Consul、Zookeeper等。
工作原理图:
负载均衡
在有多个服务提供者时,需要通过负载均衡算法的选出请求哪个 服务提供方。
默认是加权随机算法,默认权重相同,在此情况下,对应1比1的请求量。
另外还有:加权轮询、最少活跃优先+加权随机、最短响应优先+加权随机、一致性哈希(适合有状态请求)。
流量管控
Dubbo提供了路由管控策略,有负载均衡(包括多种算法)和路由策略。
大致流程:获取到的请求地址集合,经过多个路由策略,变成新的地址子集,再经过负载均衡策略选择服务进行调用。
工作原理:
多个路由器组成一个路由链共同协助。
通讯协议
Dubbo提供了自定义的高性能通讯协议:基于HTTP/2的Triple 协议和基于TCP的Dubbo2协议。
Dobbo同时支持任意协议的框架,如gRpc、Thrift、REST、JsonRPC、Hession2等。更多协议还可以自定义扩展。
扩展适配
Dubbo的扩展性可以方便将Dubbo切分成一个个的子模块,实现热插拔特性。可使用自身实现替代Dubbo原生实现。
- 协议与编码扩展:通讯协议、序列号编码协议
- 流量管控扩展:集群容错、路由策略、负载均衡、限流降级等
- 服务治理扩展:注册中心、配置中心、元数据中心
- 诊断优化扩展:日志、健康检查、流量统计、配置加载等
微服务生态
比较丰富的生态支持,不用担心治理诉求
入门实战
接下来以SpringBoot + Dubbo3来搭建演示demo
示例已上传github地址,可以下载直接学习演示。
1、创建项目dubbo-spring-boot-demo
引入pom
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<dubbo.version>3.2.0-beta.4</dubbo.version>
<spring-boot.version>2.6.6</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
2、创建3个模块,分别命名
dubbo-spring-boot-demo-interface
dubbo-spring-boot-demo-provider
dubbo-spring-boot-demo-consumer
3、对于dubbo-spring-boot-demo-interface模块
创建接口,并定义接口如下:
public interface DemoService {
String sayHello(String name);
}
4、对于dubbo-spring-boot-demo-provider模块
作为服务提供方
4.1、添加pom依赖
<dependencies>
<dependency>
<groupId>top.xudj</groupId>
<artifactId>dubbo-spring-boot-demo-interface</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-reload4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- spring boot starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
4.2、添加yaml配置
dubbo:
application:
name: dubbo-spring-boot-demo-provider
protocol:
# 定义dubbo协议
name: dubbo
port: -1
registry:
# 指定注册中心 zookeeper
address: zookeeper://${zookeeper.address:127.0.0.1}:2181
4.3、定义服务提供者实现
**
* 通过@DubboService发布dubbo服务
*/
@DubboService
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
return "hello " + name;
}
}
4.4、定义启动类
@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
5、对于dubbo-spring-boot-demo-consumer模块
作为服务消费方
5.1、增加pom依赖
<dependencies>
<dependency>
<groupId>top.xudj</groupId>
<artifactId>dubbo-spring-boot-demo-interface</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-reload4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- spring boot starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
5.2、添加yaml配置
dubbo:
application:
name: dubbo-spring-boot-demo-consumer
protocol:
# 定义dubbo协议
name: dubbo
port: -1
registry:
# 指定注册中心 zookeeper
address: zookeeper://${zookeeper.address:127.0.0.1}:2181
5.3、添加消费逻辑,调用服务提供方
@Component
public class Task implements CommandLineRunner {
@DubboReference
private DemoService demoService;
@Override
public void run(String... args) throws Exception {
String result = demoService.sayHello("world");
System.out.println("Receive result ======> " + result);
new Thread(()-> {
while (true) {
try {
Thread.sleep(1000);
System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world"));
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}).start();
}
}
5.4、定义启动类
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
6、启动注册中心
配置是以zookeeper作为注册中心。可以自行安装启动。这里给出一个通过dubbo-samples启动的简易注册中心方式,如下:
git clone --depth=1 https://github.com/apache/dubbo-samples
cd dubbo-samples 执行:./mvnw clean compile exec:java -pl tools/embedded-zookeeper
7、测试
启动服务提供方ProviderApplication
启动服务消费方ConsumerApplication
正常每秒输出:
Thu Mar 16 22:11:37 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:38 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:39 CST 2023 Receive result ======> hello world
Thu Mar 16 22:11:40 CST 2023 Receive result ======> hello world
总结
Dubbo作为一款PRC与微服务框架,已经具备了比较完整的生态,它既提供了开发框架的规范,也具备了服务治理的能力。
文中介绍了Dubbo的架构,包括总体架构与代码架构,提供的功能不仅包括文中列出的那些,还有很多治理、诊断等机制可供使用。
最后给出了Dubbo的演示示例,也可以在github下载dubbo源码,启动dubbo-demo模块下的dubbo-demo-spring-boot模块进行学习演示,如下:
1、clone代码:https://github.com/apache/dubbo
2、进入项目:mvn clean install -Dmaven.test.skip=true
3、idea导入项目
4、进行演示:dubbo-demo模块的:dubbo-demo-spring-boot,启动ProviderApplication、ConsumerApplication