分布式描述“组件运行在多个进程或节点上”,微服务描述“按业务能力拆成可独立交付的服务”。微服务通常是分布式系统,但使用多台服务器并不自动等于微服务。
三种常见形态
| 形态 | 部署 | 数据与调用 | 适用方向 |
|---|---|---|---|
| 模块化单体 | 一个应用 | 模块内调用,可共享事务 | 中小团队、业务快速变化 |
| 分布式单体 | 多个服务 | 强耦合、共同发布、共享数据 | 常见反模式 |
| 微服务 | 独立部署 | 明确契约,数据边界清楚 | 复杂业务、多个自治团队 |
模块化单体并不落后。它可以先通过目录、接口和领域边界控制耦合,等某个模块在扩容、发布、可靠性或组织上出现独立需求时再拆服务。
为什么拆开会更复杂
函数调用变成网络调用后,会新增:
- 超时、重试、限流和熔断。
- 服务发现、负载均衡和接口版本。
- 分布式追踪和跨服务日志关联。
- 数据一致性、幂等与补偿。
- 多仓库、多流水线和兼容发布。
1 | 单体:OrderService -> InventoryModule |
网络调用永远可能超时,而且“超时”不代表对方没有执行成功。
RPC、gRPC 与消息队列
同步 RPC 适合调用方必须立即得到结果;消息队列适合异步解耦、削峰和事件通知。
1 | 查询实时库存:同步 HTTP/gRPC |
gRPC 提供基于接口定义的强类型调用与流式能力,但它没有消除分布式故障,也不应把服务拆成细碎的远程函数库。
服务发现与网关
1 | 客户端 -> API Gateway -> 订单服务 |
API 网关常处理统一入口、路由、认证前置、限流和观测;服务仍要执行自己的授权检查,不能只相信“请求经过网关”。
什么时候值得拆
至少满足一个明确驱动力:
- 模块需要独立扩容或不同技术栈。
- 发布频率和故障隔离要求明显不同。
- 数据所有权已经清楚。
- 团队能够独立拥有开发、测试、上线和运维。
- 单体边界经过治理仍成为真实瓶颈。
如果只是文件太多,先重构模块;如果只是流量大,先看缓存、数据库、异步化和水平扩容,微服务不是性能快捷键。