一、基础知识
1. 为什么要用 Dubbo?
随着微服务架构演进,系统间依赖日益复杂。Dubbo 作为一款高性能 RPC 框架,提供了:
- 服务自动注册与发现
- 软负载均衡与容错机制
- 透明化远程调用
- 完善的服务治理能力
有效解决了分布式系统中服务调用、通信、治理等核心问题。
2. Dubbo 是什么?
Dubbo 是阿里巴巴开源的 高性能、轻量级 RPC 框架,支持:
- 服务自动注册/发现
- 多协议通信(默认 dubbo 协议)
- 负载均衡、集群容错
- 与 Spring 无缝集成
现为 Apache 顶级项目。
3. Dubbo 的使用场景有哪些?
- 透明远程调用:像调本地方法一样调远程服务
- 软负载均衡:替代 F5 等硬件负载设备
- 服务自动注册与发现:无需硬编码 IP,动态扩缩容
- 服务监控与治理:调用量、耗时、失败率统计
4. Dubbo 核心功能有哪些?
| 模块 | 功能 |
|---|---|
| Remoting | 网络通信抽象(NIO、同步转异步) |
| Cluster | 集群支持(负载均衡、容错、路由) |
| Registry | 服务注册与发现(对接 ZooKeeper 等) |
5. Dubbo 核心组件有哪些?
- Provider:服务提供方
- Consumer:服务消费方
- Registry:注册中心(如 ZooKeeper)
- Monitor:监控中心(统计调用数据)
- Container:服务运行容器(如 Spring 容器)
6. Dubbo 服务注册与发现流程?
- Provider 启动 → 向 Registry 注册服务地址
- Consumer 启动 → 向 Registry 订阅所需服务
- Registry 返回 Provider 地址列表(并推送变更)
- Consumer 基于负载均衡选择 Provider 调用
- 调用数据定时上报 Monitor
✅ 即使注册中心宕机,Consumer 仍可基于本地缓存继续调用。
二、架构设计
7. Dubbo 整体架构分层?
共 10 层,自上而下:
- Service:业务接口与实现
- Config:配置(ServiceConfig / ReferenceConfig)
- Proxy:透明代理(生成 Stub/Skeleton)
- Registry:服务注册发现
- Cluster:集群容错、负载均衡
- Monitor:调用监控
- Protocol:RPC 协议封装
- Exchange:请求-响应模型(同步转异步)
- Transport:网络传输(Netty / Mina)
- Serialize:序列化(Hessian、JSON 等)
8. Dubbo Monitor 实现原理?
- Consumer/Provider 通过 MonitorFilter 收集调用数据
- 数据聚合后暂存于内存 Map
- 每分钟由线程池发送至 SimpleMonitorService
- 后台线程写入文件,并定期生成图表
默认每 1 分钟聚合,每 5 分钟绘图。
三、分布式框架对比
9. 类似 Dubbo 的框架有哪些?
- Spring Cloud(主流微服务生态)
- gRPC、Thrift、Apache Thrift
10. Dubbo 和 Spring Cloud 有什么关系?
- Dubbo :SOA 时代产物,聚焦 RPC 调用与服务治理
- Spring Cloud :微服务时代生态,覆盖 配置中心、网关、熔断、链路追踪等全栈能力
11. Dubbo vs Spring Cloud 区别?
| 维度 | Dubbo | Spring Cloud |
|---|---|---|
| 通信协议 | TCP + 自定义协议(如 dubbo) | HTTP + REST |
| 性能 | 高(长连接、NIO) | 较低(HTTP 开销大) |
| 灵活性 | 强依赖接口契约 | 松耦合,跨语言友好 |
| 生态 | 专注 RPC | 全栈微服务解决方案 |
✅ 高并发内部服务 → Dubbo;快速迭代、多语言 → Spring Cloud。
12. Dubbo 和 Dubbox 区别?
- Dubbox 是当当网在 Dubbo 停更后 fork 的扩展版本
- 新增:RESTful 支持、升级依赖库、Kryo 序列化等
- 后随官方 Dubbo 重启,Dubbox 逐渐退出
四、注册中心
13. Dubbo 支持哪些注册中心?
- ZooKeeper(推荐,强一致、Watch 机制)
- Redis(基于 Pub/Sub 通知)
- Multicast(组播,无中心节点)
- Simple(简单内存注册,仅测试用)
14. 注册中心挂了,还能通信吗?
✅ 可以 。
Consumer 启动时会从注册中心拉取 Provider 列表并本地缓存,后续调用直接使用缓存地址,不受注册中心临时故障影响。
五、集群与容错
15. 负载均衡策略?
| 策略 | 说明 |
|---|---|
| Random(默认) | 随机调用,支持权重 |
| RoundRobin | 轮询,可能请求堆积 |
| LeastActive | 最少活跃调用,慢节点少接请求 |
| ConsistentHash | 一致性 Hash,相同参数总到同一节点 |
16. 集群容错方案?
| 方案 | 适用场景 |
|---|---|
| Failover(默认) | 读操作,失败自动重试其他节点 |
| Failfast | 非幂等写操作(如新增),失败立即报错 |
| Failsafe | 审计日志等,失败忽略 |
| Failback | 消息通知,失败后定时重发 |
| Forking | 高实时读,同时调多个,任一成功即返回 |
| Broadcast | 广播调用(如刷新缓存),全部执行 |
六、配置管理
17. Dubbo 配置如何加载到 Spring?
通过 Spring 的 NamespaceHandler + BeanDefinitionParser 机制:
- 解析
<dubbo:service>等自定义标签 - 转换为 Spring Bean 注入容器
18. 核心配置标签?
| 标签 | 用途 |
|---|---|
dubbo:application |
应用名、Owner 等 |
dubbo:registry |
注册中心地址 |
dubbo:protocol |
通信协议(dubbo/http 等) |
dubbo:service |
暴露服务 |
dubbo:reference |
引用远程服务 |
dubbo:provider/consumer |
默认配置 |
dubbo:method/argument |
方法/参数级配置 |
Spring Boot 中可通过
@DubboService/@DubboReference注解简化。
19. 超时设置优先级?
- Consumer 端配置 > Provider 端配置
- 推荐在 Consumer 设置,控制更灵活
20. 服务调用超时会怎样?
- 默认 重试 2 次(共 3 次调用)
- 若仍失败,抛出
RpcException
七、通信协议
21. 默认通信框架?
✅ Netty(高性能 NIO 框架)
22. 支持哪些协议?优缺点?
| 协议 | 特点 | 适用场景 |
|---|---|---|
| dubbo(默认) | 单长连接 + NIO + Hessian,高并发小数据 | 内部服务调用 |
| RMI | JDK 标准,阻塞短连接,Java 序列化 | 与老系统互操作 |
| Hessian | HTTP + 二进制,可传文件 | 跨语言(需 Hessian 支持) |
| HTTP | Spring HttpInvoker,浏览器可调 | Web 前端直连 |
| WebService | CXF 实现,XML/SOAP | 企业级系统集成 |
| Redis/Memcached | 基于缓存协议的 RPC | 特殊场景 |
八、设计模式
23. Dubbo 用了哪些设计模式?
- 工厂模式 :
ExtensionLoader.getExtension()动态加载 SPI - 装饰器 + 责任链:Filter 链(如 TimeoutFilter、MonitorFilter)
- 观察者模式:注册中心 Watch 机制,Provider 监听服务变更
- 动态代理:为 Consumer 生成代理类,屏蔽远程调用细节
九、运维管理
24. 如何兼容旧版本服务?
使用 version 属性:
xml
编辑
<dubbo:service interface="XxxService" ref="xxx" version="1.0.0"/>
<dubbo:reference interface="XxxService" version="1.0.0"/>
不同 version 服务互不干扰,实现平滑升级。
25. Dubbo Telnet 命令能做什么?
支持在线调试:
ls:查看服务列表invoke:调用方法status:查看状态help:命令帮助
需开启 telnet 端口(默认与服务端口一致)
26 & 37. 如何实现服务降级?
两种方式:
- 简单降级 :
<dubbo:reference mock="return null"/> - 自定义 Mock :实现
XxxServiceMock类,编写降级逻辑
27. 如何优雅停机?
- Dubbo 注册 JDK ShutdownHook
- 执行
kill PID(非kill -9)时:- 反注册服务
- 等待正在处理的请求完成
- 关闭线程池和连接
十、SPI 机制
28. Dubbo SPI vs Java SPI?
| 对比项 | Java SPI | Dubbo SPI |
|---|---|---|
| 加载方式 | 一次性加载所有实现 | 按需加载 |
| 扩展性 | 弱 | 支持 IOC/AOP、自适应扩展 |
| 灵活性 | 低 | 支持按 URL 参数动态选择实现 |
Dubbo SPI 是对 JDK SPI 的增强,是框架可扩展性的核心。
十一、其他特性
29. 支持分布式事务吗?
❌ 原生不支持 。
可集成 TCC-Transaction 等第三方框架,利用 Dubbo 隐式传参传递事务上下文。
30. 支持结果缓存吗?
✅ 支持声明式缓存:
xml
编辑
<dubbo:reference interface="XxxService" cache="true"/>
默认基于 LRU 内存缓存,避免重复计算。
31. 必须依赖的包?
- JDK(必须)
- 其他(如 Netty、ZooKeeper 客户端)按需引入
32. 支持哪些序列化?
- Hessian2(默认)
- FastJson
- Kryo
- Java 原生序列化(不推荐,性能差且有安全风险)
33. 安全措施?
- Token 令牌:防止绕过注册中心直连
- 服务黑白名单:控制调用方 IP 或应用
34. 服务调用是阻塞的吗?
- 默认同步阻塞
- 支持异步调用:返回
Future,或回调方式 - 底层基于 Netty NIO,单线程可并发调用多个服务
35. 服务失效踢出原理?
基于 ZooKeeper 临时节点:
- Provider 与 ZK 保持心跳
- 断开后临时节点自动删除
- Consumer 收到通知,剔除该节点
36. 能直连某个 Provider 吗?
✅ 可以:
- 配置
url="dubbo://ip:port"绕过注册中心 - 或通过 telnet 直连调试
38. 常见问题?
- 找不到服务 :检查
@DubboService是否标注 - 连不上注册中心:检查 IP、端口、网络策略
- 序列化异常:确保 Provider/Consumer 序列化方式一致
十二、RPC 原理(Dubbo 底层基础)
39--47. RPC 核心知识汇总
🔹 为什么需要 RPC?
- 解决 HTTP 短连接开销大、无服务治理等问题
- 提供高性能、长连接、服务发现、监控等能力
🔹 什么是 RPC?
远程过程调用(Remote Procedure Call),让调用远程服务如同本地方法。
🔹 RPC 调用流程:
- Client 调用本地代理(Stub)
- Stub 序列化参数 → 通过网络发送
- Server Stub 反序列化 → 调用真实服务
- 结果序列化返回 → Client Stub 反序列化 → 返回结果
🔹 RPC vs REST/SOAP/SOA
| 类型 | 协议 | 特点 |
|---|---|---|
| REST | HTTP/JSON | 简单、跨语言、性能一般 |
| SOAP | HTTP/XML | 企业级、安全、笨重 |
| RPC | TCP/自定义 | 高性能、强类型、适合内网 |
| SOA | 架构思想 | 松耦合、粗粒度服务 |
🔹 RPC 框架需解决的问题:
- 通信协议(TCP/HTTP)
- 高效序列化(Protobuf/Hessian)
- 服务寻址(ZooKeeper)
- 网络通信(Netty NIO)
- 动态代理(JDK/CGLib)
🔹 主流 RPC 框架:
- Dubbo(Java 生态首选)
- gRPC(Google,跨语言,Protobuf)
- Thrift(Facebook,多语言)
- RMI(JDK 原生,局限大)