Dubbo是一款高性能RPC(Remote Procedure Call,远程过程调用)框架,专注于分布式服务治理,提供服务发现、负载均衡、容错等能力

Dubbo架构

Dubbo的架构包含5个核心角色:

  1. Provider:服务提供者,暴露服务接口
  2. Consumer:服务消费者,调用远程服务
  3. Registry(注册中心):服务注册和发现的注册中心,存储服务元数据(如 IP、端口),支持 ZooKeeper/Nacos/Redis等注册中心
  4. Monitor(监控中心):统计服务调用次数和耗时
  5. Config Center(配置中心):动态调整参数(如超时时间)

Dubbo快速入门

采用SpringBoot+Dubbo+Zookeeper实现服务提供者和消费者之间的调用:

  • dubbo-provider: 服务提供者
  • dubbo-consumer: 服务消费者

由于提供者和消费者之间需要统一类,所以两者通常要依赖同一个公共接口,编写一个接口类:

package com.example.api;

public interface GreetingService {
String sayHello(String name);
}

创建提供者模块启动类DubboProviderApplication.java

package com.example.provider;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubbo
@SpringBootApplication
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
}
}

接口实现类GreetingServiceImpl.java

package com.example.provider;

import com.example.api.GreetingService;
import org.apache.dubbo.config.annotation.DubboService;

@DubboService
public class GreetingServiceImpl implements GreetingService {
@Override
public String sayHello(String name) {
return "Hello, " + name + " from provider!";
}
}

application.yml

server:
port: 8081

dubbo:
application:
name: dubbo-demo-provider
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880

创建消费者模块启动类DubboConsumerApplication.java:

package com.example.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.Resource;

@EnableDubbo
@SpringBootApplication
public class DubboConsumerApplication implements CommandLineRunner {

@Resource
private com.example.api.GreetingService greetingService;

public static void main(String[] args) {
SpringApplication.run(DubboConsumerApplication.class, args);
}

@Override
public void run(String... args) {
String result = greetingService.sayHello("World");
System.out.println("Received: " + result);
}
}

application.yml:

server:
port: 8082

dubbo:
application:
name: dubbo-demo-consumer
registry:
address: zookeeper://127.0.0.1:2181

Dubbo工作流程

  1. 服务暴露
    • Provider启动时向注册中心注册服务
    • 注册中心存储服务元数据(如 com.example.UserService192.168.1.1:20880
  2. 服务发现
    • Consumer订阅注册中心,获取Provider地址列表
    • 注册中心通过Watcher机制推送变更(如新增 Provider)
  3. 服务调用
    • Consumer通过负载均衡策略选择Provider
    • 通过Netty发送序列化后的请求数据
    • Provider 执行本地方法并返回结果
  4. 监控上报
    • 调用次数、耗时等数据异步上报到Monitor

Dubbo高级特性

  1. 序列化

两个机器在传输数据时,如何传输Java对象?

答:Dubbo内部已经将序列化和反序列化的过程内部封装了,我们只需要在定义pojo类时实现Serializable接口即可,一般会定义一个公共的pojo模块,让生产者和消费者都依赖该模块。

  1. 地址缓存

注册中心挂了,服务是否可以正常访问?

答:可以,因为Dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后再调用则不会访问注册中心。当服务提供者地址发生变化时,注册中心会通知服务消费者。

  1. 超时重试

服务消费者在调用服务提供者的时候如果发生了阻塞、等待的情形,如果不做处理,服务消费者会一直等待下去,在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩,Dubbo是如何解决的?

答:Dubbo利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。使用timeout属性配置超时时间,默认1000毫秒。如果出现网络抖动,则这一次请求就会失败。Dubbo还提供重试机制来避免类似问题的发生。通过retries属性来设置重试次数,默认为2次。

  1. 多版本管理

灰度发布:当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。
Dubbo中使用version属性来设置和调用同一个接口的不同版本,例如:

@Service(version = "1.0.0")	// 1.0版本
public class UserServiceImpl implements UserService {
@Override
public String getUserById(Long id) {
return "User-" + id;
}
}

Dubbo服务治理

功能 实现方式
负载均衡 Random(默认)/RoundRobin/LeastActive/一致性 Hash
集群容错 Failover(自动重试其他节点)/Failfast(快速失败)/Failsafe(忽略错误)
服务路由 基于条件规则(如 tag 路由)或脚本路由
服务降级 Mock 机制(在调用失败时返回本地模拟数据)

负载均衡策略

  • Random:按权重随机,默认值。按权重设置随机概率
  • RoundRobin:按权重轮询
  • LeastActive:最少活跃调用数,相同活跃数的随机
  • ConsistentHash:一致性Hash,相同参数的请求总是发到同一提供者

集群容错策略

  • Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器 ,默认重试2次,使用 retries 配置。一般用于读操作
  • Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于写操作
  • Failsafe Cluster:失败安全,出现异常时,直接忽略。返回一个空结果
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回
  • Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。