一、外发场景概述:从一次接口超时说起
做系统设计这些年,我接触过不少分布式项目。最让我头疼的,就是那些「发出去就管不着」的请求。说白了,就是咱们常说的外发场景。
记得有一次线上告警,业务方反馈订单状态一直没更新。查了半天才发现,问题出在一次外发调用上——系统 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 链路追踪的必要性
讲到这里,你可能会问:为什么非要搞链路追踪?直接写日志不行吗?
我的回答是:可以,但代价太高。我给你举几个亲身经历的场景:
- 性能瓶颈定位:一次交易耗时从 200ms 涨到 3s。逐个服务翻日志?不可能。有链路追踪,直接看哪个 Span 耗时最长,一抓一个准。
- 失败归因:消息推送后下游处理失败,日志只记了「处理异常」。链路追踪可以告诉你——异常触发在哪个环节、输入参数是什么、上游哪个请求导致了这条消息。
- 数据一致性校验:文件传输后业务状态没更新。有追踪 ID 就能串起:「文件上传成功」→「文件解析开始」→「解析成功但入库失败」→「失败原因为唯一键冲突」。每一步都有记录。
- 跨团队协作:一个请求可能会跨 3 个团队、5 个服务。出了事,每个团队都甩锅「我这边没问题」。链路追踪出来的 Trace 图,就是最客观的证据。
个人习惯:我负责系统设计时,会把「链路追踪」作为外发场景的必选项写入技术方案。哪怕初期只用简单的 Trace ID 透传,也比没有强。因为一旦出了问题,你再回来补追踪,成本高得多不说,数据可能已经被覆盖了。
1.4 外发场景的核心逻辑图
为了帮你更直观地理解,我画了一张核心逻辑图。它展示了三种外发类型在分布式系统中的位置,以及链路追踪需要覆盖的关键节点。
从图上可以看到,无论哪种外发类型,链路追踪都需要在「发起方 → 传输通道 → 接收方」这三段中埋下追踪点。尤其是消息推送和文件传输这种异步场景,传统的同步 Trace 方式不好使,需要自己去设计合适的上下文传递机制。
嗯,这恰恰是我们后面十几章要重点解决的难题。今天先把概念和结构搭好,后面咱们一个一个场景来攻克。