面试记录 2026-09-27
题目:各个微服务之间,有哪些调用方式?
难度:medium
标签:arch/microservice, network/rpc
评分:⭐⭐☆☆☆(2/5)
我的回答
微服务之间的调用关系,其实核心主要就是两个 RPC 跟 HTTP。其实我使用的情况下,HTTP 偏多,RPC 偏少。HTTP 的话,直接在服务的接口上进行调用即可。不同的服务间进行调用,就是接口间的互相通信,不用做额外的处理。RPC 的话,需要单独设置一下,性能更好一些,但需要单独的实现。
点评
优点:
- 提到了 HTTP 和 RPC 这两种主要方式
- 提到 RPC 性能更好、需要额外框架支持(正确)
- 结合自己项目经验说"HTTP 多 RPC 少"(真实)
不足:
- 完全没有讲同步 vs 异步这个更本质的划分——HTTP/RPC 都是同步,MQ 是异步,这是微服务通信最重要的维度
- 只列了 2 种方式,遗漏了 4-5 种主流方式:
- 同步:RESTful HTTP、gRPC、Thrift、WebSocket
- 异步:消息队列(Kafka/RabbitMQ/RocketMQ)、事件驱动(Event Bus)
- 反模式:共享数据库(DB as Message Bus,业界不推荐但存在)
- "HTTP 不用做额外处理"是错的:跨服务 HTTP 调用要考虑超时、重试、熔断、幂等、链路追踪(traceId 传递)、负载均衡,一样需要治理
- "RPC 需要单独实现"表述模糊:RPC 需要 IDL + 序列化 + 服务发现 + 负载均衡一整套生态(Dubbo/gRPC)
- 没讲协议差异:HTTP 是文本协议(JSON),gRPC 是二进制协议(Protobuf),压缩率高、多路复用
- 没讲选型场景:什么时候用同步什么时候用异步
补充:
- 通信维度分类:
- 同步:请求-响应,实时性高、耦合度高
- 异步:发布-订阅,解耦、削峰、最终一致
- 常见实现:
- RESTful HTTP + JSON:OpenFeign、Spring WebClient(HTTP/2)
- gRPC:Protobuf + HTTP/2,双向流式通信
- Dubbo:阿里 RPC 框架,Java 生态成熟
- Thrift:Facebook 出品,跨语言
- 消息队列:Kafka、RabbitMQ、RocketMQ、Pulsar
- GraphQL:查询灵活性,减少往返
- 同步调用必备治理:超时(connectTimeout + readTimeout)、重试(幂等接口才重试)、熔断(Sentinel/Hystrix/Resilience4j)、限流、链路追踪(OpenTelemetry)
完整讲解
第一部分:知识重点剖析
核心考点定位:考察对微服务通信模式的完整认知,不只是列举几个名字,而是理解同步/异步的本质差异和选型权衡。
知识点拆解:
- 同步通信:请求-响应模式,调用方阻塞等待返回。
- RESTful HTTP + JSON:简单、跨语言、易调试,OpenFeign/RestTemplate/WebClient 是主要客户端
- gRPC:HTTP/2 + Protobuf,多路复用、二进制压缩、双向流(Unary/Server-Stream/Client-Stream/Bidirectional)
- Dubbo:阿里开源,Java 生态,Netty + 自定义协议,支持多种负载均衡和容错策略
- Thrift:Facebook 开源,跨语言强,Facebook/Meta 内部主力
- 异步通信:发布-订阅模式,双方解耦。
- 消息队列:Kafka(日志)、RabbitMQ(路由)、RocketMQ(事务消息)、Pulsar(分层存储)
- 事件驱动:Event Bus、Event Sourcing,服务发布领域事件,其他服务订阅
- 反模式:
- 共享数据库(DB as Message Bus):数据强一致但强耦合,通常不推荐
- 直接调用内部函数:无法解耦、无法独立部署,违背微服务初衷
- 选型原则:
- 强一致 + 实时返回 → 同步(HTTP/gRPC)
- 解耦 + 削峰 + 最终一致 → 异步(MQ)
- 高性能 + 强类型契约 → gRPC/Dubbo
- 快速迭代 + 灵活查询 → GraphQL
递进:先分"同步 vs 异步",再在同步下细分协议,异步下细分 MQ。每种方式的治理策略也不同。
第二部分:考察方向与延伸递进
考察方向:
- 深度:gRPC 4 种流模式、Protobuf 编码原理、HTTP/2 多路复用
- 广度:与 HTTP/2、HTTP/3/QUIC 的演进关系
- 应用:同步调用的治理(超时/重试/熔断/幂等)、异步消息的可靠投递(at-least-once)
延伸递进面试题:
- HTTP 调用为什么还需要治理?"不用额外处理"错在哪?
- 解答要点:跨网络调用要考虑超时(默认不设导致线程池打满)、重试(网络抖动)、熔断(下游挂了要快速失败)、幂等(重试要安全)、链路追踪(traceId 透传)。HTTP 只是协议,治理是必需的。
- gRPC 相比 HTTP/JSON 好在哪?
- 解答要点:HTTP/2 多路复用避免队头阻塞、Protobuf 二进制压缩率高、强类型契约(.proto)、支持双向流式通信、跨语言自动代码生成。
- 什么场景必须用异步消息?
- 解答要点:下单后通知库存扣减、通知积分、通知风控——这些是副作用,可以延迟;下游挂了不能阻塞下单主流程;MQ 削峰,避免秒杀流量打爆下游。
- Feign 和 RestTemplate 和 WebClient 有什么区别?
- 解答要点:Feign 是声明式(写接口就行,OpenFeign + 负载均衡)、RestTemplate 是命令式(编程式,同步阻塞)、WebClient 是响应式(基于 Netty,支持 HTTP/2 多路复用)。Spring 官方推荐用 WebClient 替代 RestTemplate。
第三部分:面试者参考回答(300-600 字口语化)
面试官您好,微服务调用方式我按同步 vs 异步两大类来讲。
同步通信:请求-响应,调用方阻塞等待。
- RESTful HTTP + JSON:最简单,OpenFeign、WebClient 是主要客户端,几乎所有语言都支持,易调试;
- gRPC:HTTP/2 + Protobuf 二进制,多路复用、强类型契约、支持 4 种流模式(Unary/Server-Stream/Client-Stream/Bidirectional);性能比 HTTP/JSON 高,但可读性差;
- Dubbo:阿里开源,Java 生态成熟,Netty + 自定义协议,支持丰富的负载均衡和容错;
- Thrift:Facebook 出品,跨语言强,海外用得更多。
异步通信:发布-订阅,解耦。
- 消息队列:Kafka(日志流)、RabbitMQ(路由复杂)、RocketMQ(事务消息)、Pulsar(分层存储);
- 事件驱动:Event Bus + Event Sourcing,服务发领域事件,其他服务订阅;
- 反模式:共享数据库(DB as Message Bus),强耦合,一般不推荐。
选型:
- 强一致 + 实时返回(查询订单、支付确认)→ HTTP/gRPC;
- 解耦 + 削峰 + 最终一致(下单后扣库存、发通知、积分变动)→ MQ;
- 高性能强类型内部通信 → gRPC/Dubbo。
同步调用必须有治理:不能"直接调接口"就算了。要设超时(默认不设会线程池打满)、按幂等做重试、配熔断(Sentinel/Hystrix/Resilience4j)、限流、traceId 透传做链路追踪。这几点不做,生产必出问题。