一句话总结
微服务通信分两大类:同步通信(请求-响应模式,调用方等待结果)和异步通信(消息驱动,调用方不等待)。同步通信主流方案: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 | 自定义 TCP | HTTP/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。
面试官:什么时候用同步通信,什么时候用异步?
你:需要即时响应的用同步(查询、下单核心流程),不需要即时响应的用异步(发短信、送积分、数据统计)。异步可以解耦、削峰、提高系统韧性,但增加了复杂度和延迟。