服务集成方式
用途:两个服务之间要交换数据或触发处理时,选择调用方式
四种基本方式
「四种基本方式」小节链接| 方式 | 语义 | 耦合 | 失败处理 | 适用 |
|---|---|---|---|---|
| 同步 RPC/HTTP | 请求-响应,调用方等待结果 | 时间与可用性耦合 | 超时、重试、熔断、降级 | 用户交互必须立即得到结果 |
| 异步消息 | 发送事件,消费方自行处理 | 契约耦合 | 重试、死信、幂等 | 允许延迟的副作用(通知、投影、下游更新) |
| 事件订阅(Webhook/回调) | 跨组织或跨网络的异步通知 | 低 | 最大努力通知 + 主动查询 | 与外部系统集成 |
| 数据共享(同库/直连表) | 直接读对方数据 | 极高 | 无 | 反模式,除非同一 owner |
同步调用的必备配套
「同步调用的必备配套」小节链接- 超时:每个远程调用必须有明确超时(连接 + 读),且上游超时 > 下游超时链之和,避免雪崩式等待。
- 重试:只对幂等操作重试;使用退避 + 抖动;限制总重试预算,防止重试风暴。
- 熔断:错误率或慢调用比例触发熔断,半开探测恢复。
- 降级:定义不可用时的替代行为(缓存值、默认值、功能关闭),而不是抛异常给用户。
- 隔离:线程池/信号量隔离,防止单一依赖拖垮整个服务。
- 幂等:以业务键去重,覆盖网络重试与消息重复。
开源参考:Alibaba Sentinel、Resilience4j、Netflix Hystrix(已停维,思路仍适用)、gRPC 的 deadline 传播。
异步化的判断
「异步化的判断」小节链接问一句:调用方真的需要等这个结果吗? 不需要就异步。典型收益:削峰、解耦发布、故障隔离。典型代价:状态可见性延迟(用户界面需要“处理中”语义)、最终一致需要兜底对账。
契约管理
「契约管理」小节链接- 接口版本策略:新增字段向后兼容;删除或改语义必须升版本并给出共存期。
- 契约测试:消费者驱动契约(Pact、Spring Cloud Contract)在提供方 CI 中验证兼容性,避免集成环境才发现破坏。
- Schema 注册表:事件 Schema 集中管理(Avro/Protobuf/JSON Schema),带兼容性检查。
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 无超时的远程调用 | 所有出网调用统一设置超时,并在压测中验证 |
| 对所有操作盲目重试 | 非幂等操作重试会造成重复扣减/重复发货 |
| 同步链路过长(A→B→C→D) | 重划边界或改异步;链路深度是延迟与故障放大的主因 |
| 用消息队列掩盖边界错误 | 消息成为分布式单体的一部分,仍必须一起发布 |
| 跨服务分布式 join(循环调用拉数据) | 建投影/宽表或同步到搜索引擎 |
| 忽略部分失败 | 明确补偿与人工兜底路径 |
延伸阅读
「延伸阅读」小节链接- Martin Kleppmann《数据密集型应用系统设计》第 4 章(请求与流)
- Chris Richardson《微服务架构设计模式》第 5–7 章(远程调用与消息)