Apache Dubbo 是一个高可用的,基于 Java 的开源 RPC 框架。Dubbo 不仅具备 RPC 访问功能,还包含服务治理功能。
发展历程
- Dubbo 最开始是阿里巴巴内部使用的 RPC 框架
- 2011 年对外提供,随后断断续续地更新
- 2019 年捐献给 Apache,由 Apache 继续维护以后的版本
Dubbo 建构(重要)
关系
- init:创建
- async:异步
- sync:同步
角色
- Provider:提供者,编写持久层和事务代码
- Container:容器(Spring 容器),Dubbo 完全是基于 Spring 实现的
- Registry:注册中心,放置所有 Provider 对外提供的信息,包含 Provider 的 IP、访问端口、访问遵守的协议、对外提供的接口、接口中有那些方法等相关信息。
- Consumer:消费者(RPC 调用者,SOA 调用服务的项目),开发中也是一个项目,编写 service 和 controller,调用 XXXXServiceImpl 中的方法。
- Monitor:监控中心,监控 Provider 的压力情况等,每隔两分钟 Consumer 和 Provider 会把调用次数发送给 Monitor。
Dubbo 支持的协议
Dubbo 协议(官方推荐)
- 使用 NIO 复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用)。
- 大文件上传时,可能会出现问题(不使用 Dubbo 进行文件上传)。
RMI 协议
- JDK 自带的能力
- 偶尔连接失败
Hessian 协议
- 可与原生 Hessian 互操作,基于 HTTP 协议
- 需要 hessian.jar 支持,http 短连接性能开销大
Dubbo 支持的注册中心
zookeeper(官方推荐)
- 支持分布式、周边生态好
- 受限于 zookeeper 软件的稳定性,尽管其稳定性较优
Multicast
- 去中心化、不需要单独安装软件
- Provider 和 Consumer 和 Registry 不能跨路由(无法在公网使用)
Redis(优秀)
- 支持集群、性能高
- 要求服务器时间同步,否则可能出现集群失败
Simple
- 标准的 RPC 服务,没有兼容问题
- 不支持集群
第一个 Dubbo 项目
-
创建一个父工程:DubboParent
-
配置父工程依赖(注意 Dubbo 和 zookeeper 的版本兼容):
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.11</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.11</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.7.11</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.2.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-x-discovery</artifactId> <version>5.2.0</version> </dependency> </dependencies> </dependencyManagement>
-
创建 api 模块:
api 模块中的接口类,往往以
XXDubboService
来命名。public interface DemoDubboService { public String demo(String param); }
-
创建 provider 模块:
provider 模块中的类,实现了 api 模块中的接口,调用了数据库,并将服务注册到 zookeeper(或其他注册中心)。
@DubboService public class DemoDubboServiceImpl implements DemoDubboService { @Override public String demo(String param) { System.out.println("DEMO 执行中..."); return param + "ABC"; } }
@SpringBootApplication @EnableDubbo public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
dubbo: application: name: dubbo-provider registry: address: zookeeper://192.168.80.130:2181 protocol: port: 20884
在使用 Dubbo 编程时,Provider 的 Service 注解使用 @DubboService(老版本使用 dubbo 包中的 Service 注解),并且在启动类中加上 @EnableDubbo。
-
创建 consumer 模块:
consumer 模块也需要导入 api 模块,以使用其中的接口类。配置好 dubbo 的信息,并且设置
EnableDubbo
后,可以通过@DubboReference
直接将 api 模块的实现类注入。public interface DemoService { public String demo(); }
@Service public class DemoServiceImpl implements DemoService { @DubboReference // 这里使用 DubboReference 表明这应该从 Provider 中获取 DemoDubboService demoDubboService; @Override public String demo() { return demoDubboService.demo("有马加奈"); } }
@Controller public class DemoController { @Autowired private DemoService demoService; @ResponseBody @RequestMapping("/demo") public String demo() { return demoService.demo(); } }
@SpringBootApplication @EnableDubbo public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
dubbo: application: name: dubbo-consumer registry: address: zookeeper://192.168.80.130:2181
-
依次启动:zookeeper、provider 启动类、consumer 启动类,完成 consumer 对 provider 的调用。
负载均衡
- 集群:一个内容,部署多次,形成的整体成为集群。集群的每个个体都部署到不同的服务器上。
- 伪集群:集群中的内容部署到同一台服务器上,通过不同的端口区分个体。
负载均衡就是在使用集群的前提下,当访问整个集群时,分配集群中的每个结点被访问次数或频率的策略。
Dubbo 内置策略
Random:随机
随机访问集群中的结点,访问概率和权重有关。
RoundRobin:轮询
按照一定的顺序进行轮询,访问频率和权重有关。
LeastActive:最少活跃
活跃数相同的随机选择,活跃数较小的优先访问(总是分配给收到「最闲」的结点)。
ConsistentHash:一致性哈希
相同的请求参数会被发送到一个 provider。
使用 Dubbo 设置负载均衡
@DubboReference
- 可以配置负载均衡策略 loadbalance:
@DubboReference(loadbalance = "roundrobin")
DemoDubboService demoDubboService;
@DubboService
- 可以配置负载均衡策略 loadbalance。
- 可以配置(负载均衡策略的)权重 weight。
@DubboService(loadbalance = "roundrobin", weight = 4)
public class DemoDubboServiceImpl implements DemoDubboService {
配置文件中配置
全局配置所有 provider 和 consumer 的负载均衡效果。
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://192.168.80.130:2181
protocol:
port: 20884
provider:
loadbalance: random
consumer:
loadbalance: random