微服务通信概述:单体架构 vs 微服务架构

聊微服务通信之前,咱们得先搞清楚一个根本问题:为什么微服务之间要通信?

说白了,单体时代你根本不用操心这个。所有代码在一个进程里,方法调用就是一次函数跳转。但微服务一拆,每个服务独立部署,它们之间怎么协作?这就引出了通信这个核心话题。

单体架构 vs 微服务架构:通信视角的对比

我刚开始做架构转型那会儿,带团队把一个电商单体拆成十几个微服务。第一个坑就是——原来一个事务里搞定的事情,现在要跨服务调用了

咱们看个直观对比:

维度 单体架构 微服务架构
调用方式 进程内方法调用 跨进程网络调用
延迟 微秒级(内存访问) 毫秒级(网络开销)
可靠性 进程内异常处理 网络故障、超时、重试
数据一致性 本地事务 ACID 分布式事务 BASE
耦合度 紧耦合(代码级) 松耦合(接口级)

你看,从单体到微服务,通信代价至少上升了两个数量级。这不是简单的技术替换,而是整个架构思维的转变。

核心认知:微服务架构的本质,就是把「进程内调用」变成「进程间通信」。所有分布式问题,都源于这个转变。

通信模式分类:同步 vs 异步

微服务通信就两种模式,没有第三种。我习惯这么区分:同步是「你等我」,异步是「你忙你的,完事告诉我」

同步通信

最常见的就是 HTTP/REST 和 gRPC。调用方发请求,阻塞等待响应。

  • 优点:简单直观,结果立等可取
  • 缺点:调用链越长,整体延迟越大;服务间强依赖
  • 典型场景:查询类操作、实时性要求高的场景

我在项目中遇到过一个问题:订单服务调用库存服务,库存服务又去调用物流服务。三个服务串行调用,接口响应时间从 50ms 飙升到 500ms。这就是同步调用的「链式放大效应」。

异步通信

通过消息队列(Kafka、RabbitMQ)或事件总线实现。发送方只管发消息,不关心谁消费。

  • 优点:解耦彻底,削峰填谷,容错性好
  • 缺点:调试困难,最终一致性需要额外处理
  • 典型场景:订单创建后发通知、日志收集、数据同步

我的建议:能用异步就别用同步。但别走极端——查询类操作用同步,命令类操作用异步,这是比较稳妥的分界线。

RPC vs 消息队列:选型对比

很多新手会问:「RPC 和消息队列到底选哪个?」其实它们不是替代关系,而是解决不同问题的工具

对比维度 RPC(如 gRPC、Dubbo) 消息队列(如 Kafka、RabbitMQ)
通信模式 同步为主(也可异步) 异步
耦合度 接口契约强耦合 消息格式松耦合
延迟 低(毫秒级) 较高(取决于队列积压)
可靠性 依赖重试和超时 消息持久化,至少一次投递
适用场景 实时查询、命令调用 事件驱动、解耦、削峰

我个人的选型原则很简单:

  1. 需要实时响应 → RPC(比如用户查询订单状态)
  2. 需要解耦和缓冲 → 消息队列(比如下单后发短信、更新积分)
  3. 两者混用 → 大部分成熟项目都是 RPC + MQ 组合

避坑指南:我曾经在一个项目里,所有服务间通信都用消息队列。结果查询接口延迟高得离谱,用户点个按钮要等 3 秒。后来才意识到——查询类操作天生适合同步,强行异步只会增加复杂度

选型决策树

如果你还在纠结,试试这个决策思路:

  • 这个调用需要立即拿到结果吗? → 是 → RPC
  • 这个调用可以容忍几秒延迟吗? → 是 → 消息队列
  • 这个调用需要保证强一致性吗? → 是 → RPC + 分布式事务(慎用)
  • 这个调用需要削峰填谷吗? → 是 → 消息队列

嗯,说白了就是一句话:别把微服务通信想得太复杂,它本质上就是「你等我」和「你忙你的」两种选择。选对了,架构就稳了一半。

下一章咱们深入 RPC 的具体实现,聊聊 gRPC 和 Dubbo 的实战细节。到时候我会分享一些线上踩过的坑,保证让你少走弯路。