一、外发场景概述:从一次接口超时说起

做系统设计这些年,我接触过不少分布式项目。最让我头疼的,就是那些「发出去就管不着」的请求。说白了,就是咱们常说的外发场景。

记得有一次线上告警,业务方反馈订单状态一直没更新。查了半天才发现,问题出在一次外发调用上——系统 A 把消息推给了系统 B,B 处理完后回了个确认,但确认在网络传输中丢了。A 呢,等超时后直接放弃了,没做重试,也没记录日志。结果就是丢了一笔订单。

你想想看,类似的情况,在微服务架构里太常见了。今天这章,我就把外发场景的底子给你捋清楚。

1.1 什么是外发场景

外发,指的是当前系统主动向外部系统发起请求、发送数据或指令的过程。这里的「外部」,可以是另一个微服务、第三方 API、消息队列、文件服务器,甚至是用户端。

我习惯把外发场景分解为三个核心要素:

  • 发起方:主动发送请求的一方,通常是业务系统或网关
  • 接收方:处理请求的外部系统或终端
  • 传输通道:连接双方的协议和网络,比如 HTTP、RPC、MQ、FTP

外发场景最大的挑战在于——你无法控制接收方的行为。它可能挂了、慢了、返回了错误数据,甚至压根没收到。而这些,都需要你的系统主动去应对。

关键认知:外发场景的本质是「信任缺失」。你不能假设对方会正确响应,必须在自己这一侧做好兜底和追踪。

1.2 常见外发业务类型

我接触过的项目里,外发场景大致可以归为三类。咱们用一张表直观对比一下:

类型 典型协议 实时性 可靠性要求 链路追踪难点
API 调用 HTTP/REST, gRPC, Dubbo 高(同步阻塞) 中高(需重试、超时) 跨进程传递上下文,易丢失
消息推送 Kafka, RabbitMQ, MQTT 中(异步削峰) 高(需 ACK、幂等) 异步解耦后,链路易断裂
文件传输 FTP, SFTP, S3 预签名 URL 低(批量、大文件) 极高(需校验、断点续传) 非结构化数据,缺少统一 trace ID

API 调用

这是最常见的类型。系统 A 通过 HTTP 请求调用系统 B 的接口,拿到结果后继续处理。比如支付服务调用风控服务、订单服务调用库存服务。

我在一个电商项目中遇到过,单个下单请求会触发 5 次以上下游 API 调用。每次调用都可能失败、超时。如果没有链路追踪,出问题时你根本不知道是哪个下游拖慢了整个流程。

消息推送

不同于 API 调用的一问一答,消息推送是异步的。生产者发完消息就继续干自己的事,消费者什么时候处理、处理成什么样,生产者「看不到」。

这是分布式解耦的利器,也是链路追踪的噩梦。我曾经遇到过一个场景:A 系统发了条「订单已支付」的消息,B 系统消费后更新了库存,C 系统又消费更新了物流。结果 B 处理成功,C 处理失败,整个状态就乱了。你想来查?消息队列里只记录了发送成功,没有端到端的追踪信息。

文件传输

处理批量和数据量大时,文件传输就派上用场了。像银行对账、日结报表、大数据导入,都离不开这招。

文件传输的坑往往藏在「看不到」的细节里。我记得有一次,合作伙伴系统晚上传过来一批对账文件,我们的文件服务器收了,但处理程序因为磁盘满了直接忽略。第二天早上发现账对不齐——我们以为处理完了,对方以为我们还没收到。典型的「双方都以为自己是对的」。

避坑提醒:我曾经接手过一个项目,文件传输完全依赖文件名来关联业务。结果有一次文件名编码出问题,导致大量文件匹配失败。我强烈建议:文件层面做双校验(文件名 + 内容 MD5),并且传输前后都要写日志。

1.3 链路追踪的必要性

讲到这里,你可能会问:为什么非要搞链路追踪?直接写日志不行吗?

我的回答是:可以,但代价太高。我给你举几个亲身经历的场景:

  1. 性能瓶颈定位:一次交易耗时从 200ms 涨到 3s。逐个服务翻日志?不可能。有链路追踪,直接看哪个 Span 耗时最长,一抓一个准。
  2. 失败归因:消息推送后下游处理失败,日志只记了「处理异常」。链路追踪可以告诉你——异常触发在哪个环节、输入参数是什么、上游哪个请求导致了这条消息。
  3. 数据一致性校验:文件传输后业务状态没更新。有追踪 ID 就能串起:「文件上传成功」→「文件解析开始」→「解析成功但入库失败」→「失败原因为唯一键冲突」。每一步都有记录。
  4. 跨团队协作:一个请求可能会跨 3 个团队、5 个服务。出了事,每个团队都甩锅「我这边没问题」。链路追踪出来的 Trace 图,就是最客观的证据。

个人习惯:我负责系统设计时,会把「链路追踪」作为外发场景的必选项写入技术方案。哪怕初期只用简单的 Trace ID 透传,也比没有强。因为一旦出了问题,你再回来补追踪,成本高得多不说,数据可能已经被覆盖了。

1.4 外发场景的核心逻辑图

为了帮你更直观地理解,我画了一张核心逻辑图。它展示了三种外发类型在分布式系统中的位置,以及链路追踪需要覆盖的关键节点。

外发场景核心逻辑与链路追踪覆盖节点 外发场景核心逻辑图 业务系统 (发起方) API 调用 消息推送 文件传输 外部系统 (接收方) 链路追踪必需覆盖节点 • Trace ID 透传(HTTP Header) • 消息队列的 deferred trace • 文件传输的关联记录 • 超时与重试日志绑定 外发场景=不信任传递 在自己侧做好追踪

从图上可以看到,无论哪种外发类型,链路追踪都需要在「发起方 → 传输通道 → 接收方」这三段中埋下追踪点。尤其是消息推送和文件传输这种异步场景,传统的同步 Trace 方式不好使,需要自己去设计合适的上下文传递机制。

嗯,这恰恰是我们后面十几章要重点解决的难题。今天先把概念和结构搭好,后面咱们一个一个场景来攻克。