
Dubbo RPC基础与入门详解定位Dubbo 第 01 篇入门篇讲清 RPC 的本质问题、Dubbo 的定位与角色模型并给出可运行的快速上手路径与配置体系适用版本Dubbo 3.xJDK 8/17差异点标注 2.7.x目录一、RPC 本质与关键要素二、Dubbo 定位与版本演进三、核心角色与运行流程四、快速上手五、配置体系与优先级六、总结七、常见高频面试题一、RPC 本质与关键要素1.1 RPC 要解决的四个核心问题RPCRemote Procedure Call远程过程调用的目标是让调用远程服务像调用本地方法一样简单。但像本地只是表象底层必须解决四个本质问题问题含义在 Dubbo 中的落点寻址目标服务在哪台机器、哪个端口注册中心 服务发现06 篇序列化内存对象 → 可传输的字节流hessian2 / fastjson2 / protobuf05 篇传输字节可靠送达、结果可靠返回dubbo / triple 协议 Netty05 篇容错网络不可靠下的超时、重试、降级集群容错 负载均衡04 篇这四件事任何 RPC 框架都逃不掉差别只在解决质量与扩展性。1.2 本地调用与远程调用的本质差异这是理解一切分布式问题的起点本地调用 远程调用 调用延迟 纳秒级 毫秒级放大 ~10^5 倍 失败模式 只有异常 异常 超时 半成功 重复执行 参数语义 引用传递共享对象 值传递序列化 深拷贝 可用性 进程活着就能调 依赖网络 对端 注册中心三条推论贯穿整个 Dubbo 知识体系超时必须存在且必须显式配置远程调用可能发出去了但永远没响应没有超时 线程无限等待重试必须与幂等绑定超时不代表对端没执行可能执行了但响应丢了盲目重试会导致重复执行出入参是值拷贝消费方拿到的返回对象与提供方内存中的对象没有任何关联修改互不影响——也因此必须可序列化。1.3 RPC 框架的五要素一个完整的 RPC 框架由五个部件组成Dubbo 的目录分篇正是围绕它们展开调用方代码 │ ① 动态代理把方法调用转成远程请求 ▼ 代理对象 ──⑤ 集群容错重试/负载均衡/路由 │ ▼ ② 序列化对象 → 字节 ④ 服务发现从注册中心获取地址列表 │ ▼ ③ 网络传输长连接 多路复用Netty │ ▼ 提供方逆序还原执行动态代理第02 篇讲生成与调用链序列化第05 篇讲格式选型与安全网络传输第05 篇讲协议帧结构与连接模型服务发现第06 篇讲注册、订阅、推送与容灾集群容错第04 篇讲六大容错策略与负载均衡算法。二、Dubbo 定位与版本演进2.1 一句话定位Dubbo 高性能 RPC 框架 面向微服务的治理体系。它不只是发请求收响应的通信库而是把服务发现、负载均衡、容错、路由、降级、可观测性整合在一起的一体化方案。2.2 版本演进版本关键变化2.6 及以前经典形态接口级注册发现 dubbo 私有协议 Spring XML 配置为主2.7.x捐赠 Apache 后首个大版本异步编程模型改进CompletableFuture、元数据中心雏形、配置中心概念引入3.0两大核心升级应用级服务发现对齐云原生/Service MeshTriple 协议基于 HTTP/2兼容 gRPC3.3Triple 协议增强支持映射为标准 HTTP/JSON 接口curl、浏览器、网关可直调简化多语言与前后端联调两条演进主线值得记住服务发现从接口级走向应用级接口级在超大规模下注册数据爆炸06 篇展开协议从私有二进制走向 HTTP/2 标准为了与 gRPC、Service Mesh、云原生生态互通05 篇展开。2.3 与主流方案对比维度DubboSpring CloudOpenFeigngRPC协议dubboTCP 私有/ tripleHTTP/2HTTP/1.1 JSON 为主HTTP/2 Protobuf性能高二进制 长连接多路复用中文本协议开销大高服务治理内置完整容错/路由/降级/灰度组件拼装各 starter弱需自建或配 mesh服务发现内置多种注册中心适配依赖注册中心组件通常外接xDS 等跨语言3.x Triple 后显著改善天然HTTP原生跨语言典型场景Java 生态内部高频服务调用HTTP 生态、异构系统多跨语言、与 Mesh 结合选型结论Java 技术栈内部服务间高频调用Dubbo 的性能与治理完整度是首选对外/异构系统走 HTTPtriple 也可承担跨语言强诉求或多语言中台选 gRPC 或 triple。三、核心角色与运行流程3.1 四大角色┌────────────┐ 注册 ──→ │ Registry │ ←── 订阅 └─────┬──────┘ │ 地址变更推送 ▼ ┌──────────┐ 调用 ┌──────────┐ │ Provider │ ←─────── │ Consumer │ └────┬─────┘ └────┬─────┘ └──── 调用统计异步 ──→ Monitor可选角色职责关键点Provider暴露服务启动时向注册中心注册自己的地址与接口Consumer调用远程服务启动时订阅运行期收推送维护本地地址列表Registry服务目录只存谁提供了什么、在哪不经手业务调用Monitor统计中心异步收集调用次数与耗时不在调用关键路径3.2 运行流程四步0. 注册Provider 启动 → 把接口 地址 参数写入注册中心 1. 订阅Consumer 启动 → 向注册中心订阅所需接口 2. 推送提供方上下线 → 注册中心把最新地址列表推给所有订阅者 3. 调用Consumer 从【本地缓存】的地址列表中经负载均衡选一台直连调用两个决定性的设计推模型 本地缓存Consumer 拿到地址后保存在内存调用时不经过注册中心。好处调用延迟不受注册中心影响注册中心短暂抖动甚至宕机已订阅的服务仍可继续调用06 篇讲容灾细节监控旁路化调用统计是异步上报Monitor 挂了不影响调用。这也回答了高频疑问“注册中心挂了服务还能调吗”——能但新的注册/地址变更会失效新上线的 Provider 不会被发现。3.3 与 3.x 应用级发现的衔接上述流程是经典接口级模型。Dubbo 3.x 默认演进方向是应用级服务发现注册单元从接口变为应用实例接口与实例的映射放元数据中心。本篇只需知道两种模式并存细节在 06 篇展开。四、快速上手以 Spring Boot 注解方式为例3.x 标准姿势。4.1 工程三件套demo-api ← 接口 出入参 POJOProvider/Consumer 共同依赖 demo-provider ← 实现并暴露服务 demo-consumer ← 引用并调用服务API 模块设计纪律生产级要求只放接口与出入参模型不放任何实现避免实现类被打进消费方出入参必须实现Serializable禁止透传 DO/内部对象——接口是契约内部模型是私产演进策略加方法、加字段可以改签名、删字段、改字段语义必须升 version 或新接口保证新旧提供方共存期不炸。4.2 定义接口demo-apipublicinterfaceGreetingService{StringsayHello(Stringname);}publicclassUserDTOimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateLongid;privateStringname;// getter/setter ...}4.3 Provider 暴露demo-provider依赖dependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactId/dependencydependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-nacos/artifactId!-- 或 dubbo-zookeeper按注册中心选 --/dependency实现并暴露DubboService// org.apache.dubbo.config.annotation.DubboServicepublicclassGreetingServiceImplimplementsGreetingService{OverridepublicStringsayHello(Stringname){returnHello, name;}}配置application.ymldubbo:application:name:demo-providerregistry:address:nacos://127.0.0.1:8848protocol:name:dubbo# 默认私有协议3.x 可换 tripleport:20880启动类加EnableDubbo。启动后服务即注册到注册中心。4.4 Consumer 引用demo-consumerRestControllerpublicclassGreetingController{DubboReference// 注入的是远程代理不是本地 BeanprivateGreetingServicegreetingService;GetMapping(/hello)publicStringhello(RequestParamStringname){returngreetingService.sayHello(name);}}dubbo.application.name改为消费方自己的应用名其余配置同提供方。调用sayHello时实际走了完整的代理 → 集群 → 序列化 → 网络链路02 篇拆解。4.5 本地调试技巧直连模式绕过注册中心本地没有注册中心时引用处直接指定地址DubboReference(urldubbo://127.0.0.1:20880)privateGreetingServicegreetingService;直连时注册/订阅环节被跳过适合联调与单测环境。QOS 运维端口Dubbo 内置运维通道默认 22222可查在线服务、手动上下线telnet 127.0.0.1 22222 ls # 列出已导出/引用的服务五、配置体系与优先级5.1 配置模型分层Dubbo 配置按作用域从小到大组织小作用域覆盖大作用域reference / service单服务级 ← 最高业务优先级 ▲ 覆盖 consumer / provider角色全局默认 ▲ 覆盖 protocol / registry / application基础设施常见配置项归属层级典型配置说明applicationname、qos 开关应用身份注册中心按此识别registryaddress、protocol支持多个注册中心并存protocolname、port、threads暴露端口与协议providertimeout、retries、threads 默认值提供方全局兜底consumertimeout、retries、check消费方全局兜底check: false允许启动时无提供方service / reference同上单服务覆盖方法级还能再细DubboService(methods ...)超时覆盖链04 篇深讲方法级 接口级reference consumer 全局 provider 方法级 provider 接口级 provider 全局。消费方配置优先于提供方——因为等多久应由等待方决定。5.2 外部配置优先级高 → 低JVM -D 参数 ← 运维临时覆盖最高 配置中心外部化配置 ← 运行时动态下发支持不重启变更 本地配置文件 ← application.yml / dubbo.properties API 编程 / 框架默认值 ← 最低实践含义同一配置项出现在多处时高层覆盖低层生产上把环境差异项放配置中心把应急项留给 -D。5.3 服务匹配三元组Consumer 找到 Provider 的条件是三元组完全一致接口全限定名 version groupversion接口不兼容升级时新旧版本并存version 2.0.0消费方按版本路由group同一接口的不同实现分组如group perf性能压测组实现环境/流量隔离。消费方不指定 version/group 时只能匹配同样未指定的服务——跨版本/跨组匹配不到是常见找不到服务问题的根因。六、总结RPC 的本质是解决寻址、序列化、传输、容错四件事远程调用与本地调用在延迟、失败模式、参数语义上有本质差异由此推出必须配超时、重试必须幂等、出入参必须可序列化三条纪律。Dubbo 定位是高性能 RPC 治理一体化演进主线两条服务发现接口级 → 应用级协议私有二进制 → HTTP/2Triple。四大角色中注册中心只存目录不经手调用Consumer 本地缓存地址 推模型保证注册中心抖动不影响存量调用。快速上手三件套api契约、providerDubboService、consumerDubboReferenceAPI 模块只放接口与可序列化模型。配置体系小作用域覆盖大作用域方法 接口 全局外部优先级 -D 配置中心 本地文件服务匹配靠接口 version group三元组。七、常见高频面试题1. 什么是 RPC一个 RPC 框架要解决哪些核心问题要点RPC 让远程调用像本地方法调用。核心解决四件事——寻址服务发现定位目标、序列化对象转字节流、传输可靠送达与返回、容错超时/重试/降级。此外还需动态代理屏蔽远程细节。关键认知远程调用引入了本地调用没有的失败模式超时、半成功、重复执行所以超时、幂等、可序列化是三条硬纪律。2. Dubbo 和 Spring Cloud 怎么选要点协议上 Dubbo 提供二进制私有协议/HTTP2 Triple性能高于 OpenFeign 的 HTTP/1.1JSON治理上 Dubbo 内置完整容错/路由/降级/灰度Spring Cloud 靠组件拼装生态上 Spring Cloud 更贴 HTTP 生态与异构系统。结论Java 内部高频服务调用选 Dubbo对外/异构接口走 HTTP两者可通过 triple 等协议互通并非互斥。3. Dubbo 的四大角色是什么描述一次完整的服务调用流程。要点Provider、Consumer、Registry、Monitor。流程① Provider 启动向注册中心注册接口与地址② Consumer 启动订阅所需接口③ 地址变更由注册中心推送给 Consumer 更新本地缓存④ Consumer 调用时从本地地址列表经负载均衡选一台直连 Provider不经过注册中心调用统计异步上报 Monitor。关键推模型 本地缓存注册中心不在调用关键路径。4. 注册中心宕机了服务还能互相调用吗要点存量调用可以——Consumer 本地缓存了地址列表调用不经过注册中心但新增能力失效新上线的 Provider 无法被发现地址变更无法推送。所以注册中心要保证高可用集群部署同时 Dubbo 还有本地缓存文件兜底06 篇。5. Dubbo 2.7 与 3.x 的主要区别要点两大升级——① 应用级服务发现注册单元从接口变为应用实例解决超大规模下接口级注册数据爆炸并与云原生/K8s 体系对齐② Triple 协议基于 HTTP/2、兼容 gRPC改善跨语言与 Mesh 互通3.3 还支持映射为标准 HTTP/JSON。2.7 本身是 Apache 孵化版引入异步编程改进与配置中心。6. 设计 Dubbo API 接口模块有哪些纪律要点api 模块只放接口与出入参模型不放实现出入参实现 Serializable 且不透传内部 DO兼容性演进只加不改——改签名/删字段必须升 version 或新接口方法粒度要面向用例设计避免大而全接口同时注意默认超时与重试语义对接口契约的影响读接口才可默认重试。7. Dubbo 配置有多个来源优先级如何要点两层规则。外部来源优先级JVM -D 参数 配置中心外部化 本地配置文件application.yml/dubbo.properties API 编程与默认值。业务作用域优先级方法级 接口级reference/service 角色全局consumer/provider。超时以消费方配置优先因为等待方决定等待上限。8. Consumer 与 Provider 的 version 不一致会发生什么要点匹配不到。Dubbo 按接口 version group三元组精确匹配消费方未指定版本只能匹配未指定版本的服务跨版本不互通。这是服务已注册但消费方报 no provider的常见根因之一多版本并存场景需消费方显式指定目标 version或用*通配随机选一版。9. 本地开发没有注册中心怎么调试要点两种手段——① 直连模式DubboReference(url dubbo://127.0.0.1:20880)直接指定提供方地址跳过注册订阅② 使用内嵌/本地注册中心本地起 Nacos 或 Zookeeper 单机。另外 QOS 端口22222的ls命令可确认服务导出状态。10. 为什么远程调用必须显式设置超时要点远程调用存在请求发出但响应永远不来的可能对端卡死、网络分区本地调用没有这种状态没有超时调用线程会无限阻塞拖垮线程池进而雪崩。所以超时是远程调用的必备防护且要按方法业务耗时合理设置默认 1s 不一定合适并遵循消费方优先、层级覆盖的配置规则。