Spring Cloud 服务间通信方式?

2025年 阅读约 15 分钟 面试指南 · Spring Cloud

深入解析微服务通信方式:同步通信(Feign/REST/Dubbo/gRPC)vs 异步通信(MQ/事件驱动),通信协议选型、序列化方式对比、最佳实践,附面试模拟问答。

一句话总结

微服务通信分两大类:同步通信(请求-响应模式,调用方等待结果)和异步通信(消息驱动,调用方不等待)。同步通信主流方案:Feign(HTTP/REST,简单通用)、Dubbo(RPC,高性能)、gRPC(Protobuf,多语言)。异步通信主流方案:RocketMQ/Kafka/RabbitMQ。选型原则:查询类用同步 REST,命令类需要即时结果用同步 RPC,通知类不需要即时结果用异步 MQ

初级理解

同步 vs 异步通信

对比维度同步通信异步通信
模式请求-响应发布-订阅 / 消息队列
耦合度高(调用方依赖被调用方)低(通过消息解耦)
实时性高(即时响应)低(最终一致)
适用场景查询、需要即时结果通知、异步处理、削峰
缺点级联失败风险复杂度增加、延迟

中级深入

Feign vs Dubbo vs gRPC

对比维度Feign (HTTP)Dubbo (RPC)gRPC
协议HTTP/1.1自定义 TCPHTTP/2
序列化JSON(文本)Hessian2(二进制)Protobuf(二进制)
性能较低
跨语言支持仅 Java支持
调试方便(浏览器/Postman)需专用工具需专用工具
适用通用场景Java 高性能场景多语言高性能场景

序列化方式对比

# JSON(文本序列化) # 优点:可读性好、跨语言、调试方便 # 缺点:体积大、解析慢、不支持复杂类型 # 适用:Feign、REST API # Hessian2(二进制序列化) # 优点:体积小、速度快、支持复杂类型 # 缺点:跨语言支持弱 # 适用:Dubbo # Protobuf(二进制序列化) # 优点:体积最小、速度最快、跨语言、强类型 # 缺点:需要定义 .proto 文件、可读性差 # 适用:gRPC # 性能对比(序列化 1000 个对象) # Protobuf:10ms,5KB # Hessian2:15ms,8KB # JSON:30ms,25KB

高级拓展

事件驱动架构

# 事件驱动:通过事件解耦服务 # 场景:用户注册 # 传统方式(同步): # 注册服务 → 调用邮件服务 → 调用短信服务 → 调用积分服务 # 问题:级联调用,任一失败影响注册 # 事件驱动(异步): # 注册服务 → 发布"用户注册事件"到 MQ # 邮件服务 ← 订阅事件 → 发送邮件 # 短信服务 ← 订阅事件 → 发送短信 # 积分服务 ← 订阅事件 → 赠送积分 # 优点:解耦、独立处理、失败不影响注册 # Spring Cloud Stream(消息驱动) @EnableBinding(Source.class) public class UserService { @Autowired private Source source; public void register(User user) { // 保存用户 userDao.save(user); // 发布事件 source.output().send(MessageBuilder .withPayload(new UserRegisteredEvent(user)) .build()); } }

通信选型最佳实践

# 选型决策树 # 1. 是否需要即时响应? # 是 → 同步通信 # 否 → 异步通信(MQ) # 2. 同步通信选型 # 对外 API / 跨语言 → REST(Feign) # 内部 Java 服务 / 高性能 → Dubbo # 多语言 / 流式传输 → gRPC # 3. 异步通信选型 # 高吞吐 / 日志 / 流处理 → Kafka # 事务消息 / 可靠性高 → RocketMQ # 通用场景 / 灵活路由 → RabbitMQ # 4. 混合使用 # 查询:同步 REST # 命令(需即时结果):同步 RPC # 通知(不需即时结果):异步 MQ

实战场景

场景:下单流程的通信设计

# 下单流程通信设计 # 1. 用户点击下单 → 同步调用订单服务(Feign) # 2. 订单服务创建订单 → 同步调用库存服务扣库存(Feign) # 3. 订单创建成功 → 异步发送"订单创建事件"到 MQ # 4. 短信服务消费事件 → 发送下单成功短信 # 5. 积分服务消费事件 → 赠送积分 # 6. 数据分析服务消费事件 → 记录用户行为 # 为什么这样设计? # 下单核心流程(创建订单+扣库存)需要即时结果 → 同步 # 短信/积分/数据分析不需要即时结果 → 异步 # 异步处理失败不影响下单核心流程

面试模拟

面试官:Feign 和 Dubbo 怎么选?

你:Feign 基于 HTTP,简单通用、跨语言、调试方便,适合通用场景。Dubbo 基于 TCP 自定义协议,性能更高、功能更丰富(服务治理),但仅限 Java。内部 Java 微服务推荐 Dubbo,对外 API 或跨语言推荐 Feign。

面试官:什么时候用同步通信,什么时候用异步?

你:需要即时响应的用同步(查询、下单核心流程),不需要即时响应的用异步(发短信、送积分、数据统计)。异步可以解耦、削峰、提高系统韧性,但增加了复杂度和延迟。