本轮 Dubbo服务框架面试题库(带答案)
生成时间:2026-06-19 23:14 CST | 第13轮 | 共10题
【面试题】1. 注册中心(如Zookeeper)宕机后,Dubbo服务调用会受影响吗?为什么?
【标准答案】不会受影响。因为Dubbo在启动时会把Provider列表缓存到Consumer本地文件(~/.dubbo/目录下的registry缓存文件),即使注册中心挂了,Consumer也能从本地缓存中拿到服务地址列表继续调用。新服务上线/下线会感知不到,但存量调用不受影响。这也是Dubbo相比Spring Cloud的一个优势——不强依赖注册中心在线。当然,Consumer重启就不行了,因为没有地方拉地址列表,所以注册中心还是要尽快恢复。
【面试题】2. Dubbo的@Activate注解是干什么的?和@Adaptive注解有什么区别?
【标准答案】@Activate是"自动激活",用于告诉Dubbo框架"在某些条件下自动加载这个扩展点"。比如内置的ExceptionFilter、TimeoutFilter都加了@Activate,框架启动时自动生效,不需要手动配置。它支持group属性区分Provider端还是Consumer端加载。@Adaptive是"自适应",用动态代理的方式根据URL参数决定到底调用哪个实现类,比如Protocol$Adaptive会根据URL里的protocol=dubbo还是protocol=rest来路由到对应实现。简单的说:@Activate是"条件触发自动加载",@Adaptive是"运行时动态路由"。
【面试题】3. Dubbo协议采用单一长连接+NIO的设计,为什么要这样做?有什么优缺?
【标准答案】Dubbo协议默认是单一长连接+NIO,这是针对服务间高频小数据量调用做的优化。优点是:省去反复TCP握手开销,连接复用减少资源消耗,NIO异步实现高吞吐。缺点也很明显:一是不适合传输大文件,单一连接带宽有限;二是长连接下的请求会乱序到达,所以Dubbo协议头里带requestId来保证请求响应匹配。如果服务间需要传大文件或者流式数据,建议换Triple协议(HTTP2)或者REST协议,不走dubbo协议。
【面试题】4. Dubbo的Failback失败自动恢复是什么原理?和Failover有什么区别?适用什么场景?
【标准答案】Failback是"先记录、后重试"。调用失败后不会立即重试,而是把这次失败的请求信息放入一个定时任务队列,后台线程每隔5秒批量重新发送。和Failover的区别:Failover是同步重试(等重试结果返回给调用方),Failback是异步恢复(先返回null给调用方,后续再补)。适用场景:消息通知、日志上报、非核心数据同步,允许最终一致、但不能丢的请求。不适合需要立即返回结果的场景。
【面试题】5. 如何自定义一个Dubbo负载均衡策略?比如实现按客户端IP哈希的LoadBalance。
【标准答案】三步走:第一步,实现LoadBalance接口,继承AbstractLoadBalance,重写doSelect方法,拿到invokers列表和URL中的remote.ip参数做哈希取模;第二步,在META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance文件中添加myip=com.xxx.MyIPHashLoadBalance;第三步,Consumer端配置loadbalance="myip"即可。关键在于通过SPI扩展机制注册,不需要改框架源码。另外注意doSelect中要处理invokers列表变动的情况,用一致性哈希避免节点变动时大量请求漂移。
【面试题】6. Dubbo的异步调用怎么实现?AsyncContext方式和CompletableFuture方式有什么区别?
【标准答案】Dubbo支持两种异步方式。AsyncContext方式(2.6.x及之前):Consumer端配置async=true,通过RpcContext.getContext().getFuture()拿到Future然后get结果,适用于旧版本。CompletableFuture方式(2.7+推荐):接口返回值直接定义为CompletableFuture,Provider在实现里用CompletableFuture.supplyAsync()异步处理并返回。区别:AsyncContext是框架层异步,业务接口还是同步签名;CompletableFuture是业务层异步,接口返回值天然异步,链式编程支持thenApply/thenCompose等组合操作,语义更清晰,编码体验更好。新项目建议直接用CompletableFuture。
【面试题】7. Dubbo3的Triple协议是如何做到gRPC兼容的?跨语言调用是怎么实现的?
【标准答案】Triple协议本质是基于HTTP2的流式RPC协议,它的协议头设计兼容gRPC,所以gRPC客户端可以直接调用Dubbo的Triple服务。跨语言依赖两方面:一是传输层统一用HTTP2,内容层统一用Protobuf序列化(因为Protobuf有各语言SDK);二是Dubbo3支持通过protobuf IDL文件生成多语言桩代码(Java/Go/Node.js/Python等),各语言只需按照相同的.proto定义去生成客户端和服务端,就能互相调用。比如Go的gRPC客户端可以直接调Java的Dubbo3 Triple服务,不需要任何网关或适配层。
【面试题】8. Dubbo的本地存根(Stub)和本地伪装(Mock)有什么区别?怎么配置使用?
【标准答案】核心区别:Stub是"预处理",在调用远程服务前,Consumer端可以做参数验证、缓存判断等逻辑,如果有缓存命中直接返回不走远程调用,这是性能优化手段。Mock是"容灾兜底",当远程调用失败(网络超时、Provider挂了)时,Mock返回一个降级结果,保证Consumer不报错。配置上:Stub在<dubbo:reference stub="com.xxx.StubImpl"/>中指定,Mock在<dubbo:reference mock="com.xxx.MockImpl"/>或者直接mock="return null"。同一套接口可以同时有Stub和Mock,先走Stub处理参数,再走网络调用,失败后走Mock兜底。
【面试题】9. Dubbo的服务直连(绕过注册中心)怎么做?什么场景需要用?Consumer重启后还有效吗?
【标准答案】两种直连方式:一是在Consumer的<dubbo:reference>中配url="dubbo://192.168.1.100:20880",直接指定Provider地址,不走注册中心发现;二是在JVM启动参数中加-Ddubbo.resolve.file=xxx.properties指定一个地址映射文件,文件里写接口名=dubbo://ip:port。适用场景:本地开发调试(不需要连注册中心)、生产环境注册中心整体故障时的紧急恢复手段、压测时指定某台Provider。注意Consumer重启后直连配置仍然有效(写在配置里的),但这台Provider挂了就彻底不可用了,没有故障转移能力,所以只适合临时场景。
【面试题】10. Dubbo的事件通知机制(oninvoke/onreturn/onthrow)怎么用?有什么实际场景和注意事项?
【标准答案】Dubbo支持在调用远程方法时注册三个回调:oninvoke(调用前触发)、onreturn(正常返回后触发)、onthrow(抛出异常后触发)。配置方式是在Consumer的<dubbo:reference>上使用<dubbo:method name="xxx" oninvoke="notifyBean.invoke" onreturn="notifyBean.onreturn" onthrow="notifyBean.onthrow"/>,notifyBean实现了对应的回调接口。实际场景:记录调用耗时(oninvoke打时间戳+onreturn算差值)、调用失败告警(onthrow发钉钉消息)、审计日志、分布式链路追踪埋点。注意:回调方法在Consumer的IO线程中执行,不能在里面做耗时操作,否则会阻塞IO线程影响吞吐。另外onreturn的参数签名必须和原始方法一致,只是多了第一个参数放返回值。