Dubbo学习(一):Dubbo介绍
一、Dubbo简介
1、什么是Dubbo
Dubbo是一款高性能、高可用的、基于Java开源的RPC框架;由阿里巴巴开发并开源,
现为 Apache 顶级项目;它提供了三大核心功能,即:
(1)面向接口的远程方法调用
(2)智能容错和负载均衡
(3)服务自动注册和发现
所以 Dubbo框架不仅仅是具备RPC访问功能,还包含服务治理功能;
2、Dubbo核心架构
2.1、Dubbo架构图
Dubbo 架构图如下所示:
注:上图中虚线表示异步,实线表示同步;异步不阻塞线程性能高,同步阻塞线程必须
等待响应结果才能继续执行,相对性能低
2.2、Dubbo 架构中的角色
由上图中可以发现,在Dubbo 中主要包含 Provicer、Consumer、Registry、Container、
Monitor 等角色,下边分别对这些角色及功能进行介绍。
2.2.1、Provicer
Provicer 是服务提供者,暴露服务供消费者调用,处理消费者请求;在项目启动时,
Provicer 主动向注册中心注册自己提供的服务;另外 Provicer 主要实现具体的业务逻辑,
并定期向监控中心发送调用统计数据;
注意:
Provicer 暴露的对外提供服务的接口并不是在 Provicer 项目中定义的,该服务接口
是单独定义在一个项目中,Provicer 中对外的服务需要实现该接口,然后由Consumer
客户端调用。该服务接口在 Consumer远程调用 Provicer 过程中起到“桥梁”的作用;
2.2.2、Consumer
Consumer 是服务消费者,用于远程调用其他服务;启动时,向注册中心订阅所需的服
务,获取服务提供者的列表并缓存,通过负载均衡策略选择提供者;Consumer也会定期
向监控中心发送调用统计数据
2.2.3、Registry
Registry 是服务注册中心(提供服务注册与发现),放置所有Provider对外提供的信息。
包含Provider的IP,访问端口,访问遵守的协议,对外提供的接口,接口中有哪些方法
等相关信息;
Dubbo常用的注册中心有:Zookeeper、Nacos、Redis、Multicast、Simple
另外,客户端 Consumer 要想订阅到目标Provicer服务,则也需要注册到注册中心中,
如下图所示:
注:以zookeeper作为注册中心为例
2.2.4、Container
Container 是服务运行的容器,一般指spring容器,因为Dubbo是完全基于spring实现的;
负责启动、加载和运行服务提供者、管理服务生命周期和提供必要的运行环境支持
2.2.5、Monitor
Monitor 是监控中心,监控Provider的压力情况等。每隔2分钟Consumer和Provider会把
调用次数发送给Monitor,由Monitor进行统计
2.3、Dubbo的执行流程
以上边Dubbo架构图中的步骤顺序来看下Dubbo的执行流程。
Step 0 start :
启动容器(即spring 容器)时,会把Provicer启动,并将服务接口实现类封装为
Invoker,接着将 Invoker 转换为 Exporter;最后通过具体的 Protocol 协议将服务
暴露到网络中供Consumer调用
Step 1 register :
把Provider服务注册到Registry里,注册内容包括服务提供者地址、接口、方法等信息
Step 2 subscribe :
Consumer消费者启动时,从注册中心订阅所需服务,
Step 3 notify :
注册中心返回提供者地址列表给Consumer,Consumer缓存服务提供者Provider列表
Step 4 invoke :
Consumer消费者根据注册中心Registry提供的服务提供者信息,并通过 ProxyFactory
创建服务接口的代理对象,代理对象内部封装了远程调用逻辑,可以远程调用服务提
供者
Step 5 count:
Consumer和Provider把调用次数信息异步发送给Monitor进行统计
3、Dubbo 支持的协议介绍
3.1、Dubbo支持的协议
一般Provider需要配置Dubbo的协议,Consumer不需要配置
3.1.1、Dubbo协议(官方推荐)
优点:采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,
性能较好(推荐使用)
缺点:大文件上传时,可能出现问题(不使用Dubbo文件上传)
3.1.2、RMI(Remote Method Invocation)协议
优点:JDK自带的功能,不用引入其他依赖,兼容性好,
缺点:偶尔连接失败
3.1.3、Hessian协议
优点:可与原生Hessian互操作,基于HTTP协议
缺点:需hessian.jar支持,http短连接的开销大
二、第一个Dubbo练习示例
1、创建父工程dubbo-demo,dubbo-demo包含3个子模块,分别是api(定义服务接口)、
provider(服务提供者)和consumer(消费者);因为 provider和consumer都要引入
api 模块,所以我们把公用的dubbo依赖放在api模块中,
导入dubbo依赖如下:
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId></dependency><!-- curator-recipes --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId></dependency><!-- curator-framework --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId></dependency>
2、api 模块
api 中只用来定义Provider 的对外服务接口,其他什么也不干,也不需要启动;
Provider 的对外提供的服务需要实现api 中相关的接口;consumer中需要api的接口来实现远
程调用;所以 provider和consumer都要引入api模块。
示例代码如下所示:
/***************************************************** API 在Dubbo,更像是 服务端Provider与客户端Consumer 中间的桥梁,* 在API 中定义 Provider 对外暴露服务的接口,该接口由 Provider 实现,并使用* Dubbo 注解 @DubboService 标识该接口的实现类是Provider暴露的服务;* 该接口由Consumer 客户端调用** @author * @date 2025/6/4 15:39****************************************************/
public interface DubboDemoService {String demo(String name);
}
3、provider 模块
1)定义对外提供的服务,该服务需要实现api中定义的服务接口并使用Dubbo中的注解
@DubboService 标识该类是一个Dubbo服务,示例代码如下:
import com.msb.dubbo.api.service.DubboDemoService;
import org.apache.dubbo.config.annotation.DubboService;/***************************************************** todo: 注意:* 1)该类需要加上 注解@DubboService(或apache dubbo 包下的@Service) ,标识该类是一个Dubbo服务,* 才能被注册,* 2)该类需要实现API 端定义的接口** @author * @date 2025/6/4 15:50****************************************************/
@DubboService
public class DubboDemoServiceImpl implements DubboDemoService {@Overridepublic String demo(String name) {return name+" hello Dubbo test!";}
}
2)在启动类上添加注解 @EnableDubbo 开启dubbo应用,示例代码如下:
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/***************************************************** dubbo 使用步骤:* 1、定义api接口模块,如: api;在客户端模块定义对外接口* 2、定义服务端Provider,如:provider,服务端需要引入客户端依赖,* 3、在服务端定义Dubbo服务,并实现客户端定义的对外接口* 4、在服务端开启Dubbo,如在启动类上加上注解 @EnableDubbo* 5、Consumer 客户端通过 api中的接口实现远程调用** @author * @date 2025/6/4 15:44****************************************************/
@EnableDubbo //启用dubbo
@SpringBootApplication
public class DubboProviderApplication {public static void main(String[] args) {SpringApplication.run(DubboProviderApplication.class);}
}
3)配置Dubbo 信息
provider 需要配置protocol 协议信息,而consumer客户端不需要该项配置
配置信息如下:
dubbo:application:#dubbo注册到服务中心的服务名称name: dubbo-providerregistry:#dubbo注册中心地址,zookeeper表示这里以zookeeper作为注册中心address: zookeeper://47.117.80.49:2181#配置dubbo连接zookeeper的超时时间timeout: 10000#配置dubbo 协议端口号protocol:port: 20884#注意:此属性有默认值,但还需要手动指定,否则有可能报错name: dubbo
4、consumer 模块
consumer 是远程服务的调用者,在 consumer 中通过api中定义的服务接口来执行远程调用
,有一点需要注意,注入 api 提供的服务接口时需要使用注解 @DubboReference。
步骤如下:
1)定义正常的service服务,该服务正常使用spring提供的@Service 注解,或spring提供的
其他注解,但 注入 api 提供的服务接口时需要使用Dubbo提供的解 @DubboReference
示例代码如下:
/****************************************************** @author * @date 2025/6/4 16:24****************************************************/
public interface DubboDemoService {public String demo();
}/****************************************************** @author * @date 2025/6/4 16:26****************************************************/
@Service
public class DubboDemoServiceImpl implements DubboDemoService {/*** 标识从dubbo 注册中心获取服务,即通过dubbo 实现客户端 Consumer调用服务端Provider的接口;* 在这个过程中 api模块起到一个桥梁作用*/@DubboReferenceprivate com.msb.dubbo.api.service.DubboDemoService dubboDemoService;@Overridepublic String demo() {return dubboDemoService.demo("张三丰");}/****************************************************** @author * @date 2025/6/4 16:29****************************************************/
@RestController
public class DubboDemoController {@Autowiredprivate DubboDemoService dubboDemoService;@RequestMapping("/test")public String test(){return dubboDemoService.demo();}
}
2)在启动类上添加注解 @EnableDubbo 开启dubbo应用,示例代码如下:
/****************************************************** @author * @date 2025/6/4 16:23****************************************************/
@EnableDubbo
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class);}
}
3)配置Dubbo 信息
server:port: 8003#配置dubbo
dubbo:application:#配置服务名称,在dubbo中的服务名称name: dubbo-consumerregistry:#配置注册中心地址,这里用zookeeper作为dubbo注册中心address: zookeeper://47.117.80.49:2181timeout: 10000