主题
面试题蒸馏卡:Dubbo
问题:Dubbo 是什么?怎么工作?怎么保证高可用(容错/负载均衡)?怎么扩展(SPI)?和 Spring Cloud 怎么选?
高频问题与标准答
1. Dubbo 是什么?为什么用?
- 定位:阿里开源、Apache 孵化的高性能 Java RPC 分布式服务框架 + SOA 服务治理方案,可无缝集成 Spring。
- 为什么:服务化后调用与依赖复杂(SOA 背景),需要封装服务提供/调用/连接/协议/序列化/发现/路由/日志的框架。
- 三大核心功能:① Remoting(网络通信,多种 NIO 框架抽象封装);② Cluster(集群容错:多协议/软负载/失败容错/路由/动态配置);③ Registry(服务注册发现,地址透明、平滑加减机器)。
2. 核心组件与调用流程?
- 五节点:Provider(提供方)/ Consumer(消费方)/ Registry(注册中心)/ Monitor(监控)/ Container(容器)。
- 流程:Container 启动加载 Provider → Provider 注册到 Registry → Consumer 订阅(Registry 返回地址列表,变更推送)→ Consumer 按负载均衡选一台调用 → 失败换一台 → 双方统计调用次数/耗时上报 Monitor(每分钟)。
3. 服务暴露与引用流程?
- 暴露:Spring 容器刷新触发 ContextRefreshEvent → ServiceBean.onApplicationEvent → ServiceConfig.export → ProxyFactory 生成 Invoker(javassist/JDK 代理)→ DubboProtocol 转 Exporter → 启动 Server 监听端口 → RegistryProtocol 注册到注册中心。
- 引用:Consumer 订阅服务(全量缓存本地,变更监听更新)→ DubboProtocol 连接 Provider 建 Invoker → 为接口生成代理对象 → 完成引用。
4. 有哪些集群容错策略?默认哪个?
| 策略 | 行为 | 场景 |
|---|---|---|
| Failover(默认) | 失败重试其他节点(retries 默认 2) | 读操作 |
| Failfast | 只调一次失败即抛 | 非幂等写操作 |
| Failsafe | 异常记日志忽略 | 审计日志 |
| Failback | 后台记录定时重发(5s) | 消息通知 |
| Forking | 并行调用任一成功即返回 | 实时性读操作(耗资源) |
| Broadcast | 广播所有节点任一报错则报错 | 更新缓存/日志 |
5. 有哪些负载均衡策略?默认哪个?
Random(默认,加权随机) / RoundRobin(加权轮询,有慢机器请求累积问题)/ LeastActive(最少活跃数,慢机器少接请求)/ ConsistentHash(相同参数 hash 到同一 Provider,默认 160 虚拟节点)。——详见 概念卡片:Dubbo集群容错与负载均衡。
6. 支持哪些协议?为什么默认 dubbo 协议?
- 协议:dubbo(推荐)/ rmi / hessian / http / webservice / thrift / memcached / redis。
- dubbo 协议 = 单一长连接 + NIO 异步 + TCP + Hessian 序列化,适合大并发小数据量、消费者远大于提供者。
- 为什么消费者要多:单连接经验上限约 7MB/s,1 个 Provider 约需 20 个 Consumer 压满千兆网卡。
- 为什么不能传大包:单包 500KB 时单连接约 14 TPS、总带宽 262 TPS,网络成瓶颈;大文件改用 rmi/http。
7. 注册中心有哪些?挂掉还能通信吗?
- Zookeeper(推荐) / Redis / Multicast / Simple。
- 注册中心挂掉不影响已运行的调用:Consumer 启动时把 Provider 列表缓存本地,按缓存地址调用;但无法发现新服务。Registry/Provider/Consumer 三者长连接(Monitor 除外)。
8. Dubbo 和 Spring Cloud 的区别?
| 维度 | Dubbo | Spring Cloud |
|---|---|---|
| 时代 | SOA 时代,聚焦服务调用/治理 | 微服务时代,全家桶生态 |
| 通信 | RPC(TCP + Netty + Hessian 二进制) | HTTP + REST(JSON 报文大、带宽多) |
| 注册中心 | Zookeeper/Redis | Eureka/Nacos |
| 依赖 | 代码级强依赖(jar 包) | 契约松散,无代码强依赖 |
| 生态 | 网关/配置/断路器需自己补 | 网关/配置/熔断/追踪全都有 |
9. Dubbo SPI 和 Java SPI 区别?
Java SPI 一次性全量加载;Dubbo SPI 延迟加载 + IOC(setter 注入扩展点)+ AOP + 自适应扩展,按 key 只加载需要的,扩展不改源码(classpath 加配置即可)。——详见 [概念卡片:Dubbo SPI扩展机制](./概念卡片:Dubbo SPI扩展机制)。
10. 失效踢出 / 优雅停机 / 降级怎么做?
- 失效踢出:Provider 在 ZK 注册临时节点,会话断开节点消失,Consumer 感知剔除。
- 优雅停机:JDK ShutdownHook;
kill -9不会执行,kill PID才会。 - 降级:
mock="return null"或mock="true"+ 同路径接口名+Mock类实现降级逻辑;mock="force"强制走 Mock。 - 多版本/分组:
version版本过渡(新旧互不引用);同接口多实现用group分组。
11. 让你设计一个 RPC 框架,怎么做?
- 注册中心(服务注册发现,Consumer 缓存地址列表);
- 负载均衡(选节点)+ 容错重试(失败处理);
- 通信协议封装(TCP/HTTP + 序列化);
- 可选增强:监控统计、动态配置、日志、服务降级。
追问链
- 超时怎么设置? Provider 端尽量配(更懂服务),Consumer 端配了以 Consumer 为准(优先级高)。
- 调用是阻塞的吗? 默认同步阻塞;支持异步(NIO 非阻塞,返回 Future 对象),客户端无需多线程即可并行调多个远程服务。
- 注册中心是必须的吗? 不是——可点对点直连(开发测试,绕过注册中心,忽略 Provider 列表);注册中心与监控中心都是可选的。
- 服务调用链过长怎么办? 用 Pinpoint / Skywalking 做分布式链路追踪。
- 能传大文件吗? dubbo 协议不适合(单连接带宽上限),用 rmi/http 协议。
- 支持分布式事务吗? 原生不支持;可用 tcc-transaction(TCC 补偿框架,靠 Dubbo 隐式传参避免入侵业务代码)。
- 启动时依赖服务不可用会怎样? 默认
check="true"启动即抛异常阻止初始化;可配check="false"关闭。
常见误解
- ❌ "Dubbo 只能配 Zookeeper" —— Redis/Multicast/Simple 都行,ZK 只是最推荐。
- ❌ "注册中心挂了服务就断了" —— 本地缓存仍可调用,只是不能发现新服务。
- ❌ "负载均衡是服务端做的" —— 是 Consumer 端软负载,客户端本地选节点。
- ❌ "Spring Cloud 一定比 Dubbo 好" —— 追求通信性能/强治理选 Dubbo;追求生态完备/松耦合选 Spring Cloud,无绝对优劣。
关联
- 调用链:[概念卡片:Dubbo RPC框架](./概念卡片:Dubbo RPC框架)
- 容错/协议:概念卡片:Dubbo集群容错与负载均衡
- 扩展机制:[概念卡片:Dubbo SPI扩展机制](./概念卡片:Dubbo SPI扩展机制)
- 总览:RPC技术栈总览 · 微服务技术栈总览
- 注册中心:概念卡片:Zookeeper协调服务