你有没有遇到过这种场景:后端说自己没收到请求,前端却说请求已经发出去了;App 在用户手里报了一个错,日志里只有状态码;测试想在下游接口上制造一个 5 秒超时,又不敢动生产配置。这时候,你最需要的其实不是更强的日志系统,而是一个站在客户端和服务端之间,帮忙查看、改写、再原样转发的工具。这类工具在圈子里通常被叫做“中间人工具”或“请求中转工具”,也有人管它叫“中间层工具”。我更愿意用后面这个名字,因为它描述的并不是某一个具体软件,而是一类共通的架构位置:在数据必经的链路上,插一道可控的关卡。
中间层工具能做的事,本质上只有四件:截获请求、读取内容、按规则改写、转发给目标。响应回来时,再反着做一遍,让客户端也能拿到被加工过的结果。正是这个“双向拦截”的机制,让开发、测试、运维可以把黑盒变成白盒,把不可复现的问题变成可回放的问题。这篇文章会把这类工具的来龙去脉讲透:它到底解决什么问题、有哪几种形态、选型时该看什么、怎么从零搭一套能用的调试环境,以及我在实际项目中踩过的坑。适合正在搞接口联调的前后端同学、写自动化用例的测试工程师,以及想看清线上流量的运维同学。
1. 中间层工具到底在解决什么问题?
1.1 没有中间层时,调试链路有多痛
在没有中间层工具的年代,想定位一次接口异常非常难受。客户端直连服务端,你能拿到的信息基本只有应用层日志。如果想知道 HTTP 请求行、请求头、请求体具体长什么样,往往只能拜托后端翻 access log,或者靠客户端埋点重新发一版。可日志不会告诉你每一次重定向、每次 Cookie 更新、请求体字段的原始顺序,也不会帮你复现用户手机上出现的奇怪指纹。
更要命的是“多方互相甩锅”的场景。前端咬定自己传了参数,后端咬定收到的参数就不是那个值。这时候如果没有中间层,你只能继续放大日志、加追踪ID、灰度发布、再等用户反馈,一个简单问题能拖上两三天。我在刚工作那几年就吃过这种亏:线上一个订单状态不同步,前后端各加了三轮日志,最后才发现是旧的网关配置把callback参数给截断了。当时要是有一个能完整看到链路数据的中间层工具,这个问题半小时内就能定位。
另一个痛点是“状态不可控”。正常联调时,后端接口经常还没写好,或者只写好了 happy path。前端等不到数据,只能自己 mock,但 mock 数据往往和真实结构有偏差。测试想模拟超时、返回非 JSON、断网、重复推送,在直连架构下很难做。没有中间层,所有这些工作都得改代码、发版本、等构建,效率极低。中间层工具的诞生,本质上就是把“链路观测”和“链路干预”这两件事从前删掉,变成一个独立的能力,谁需要谁接入。
1.2 中间层工具的工作模型:截获、改写、转送
理解中间层工具,最简单的方式是拿快递驿站类比。客户端寄一个包裹,正常情况下快递员直接送到服务端手里。中间层工具相当于在路上建了一个驿站:包裹到了驿站,驿站工作人员先拆开看一眼,照个相,必要时把里面的东西换一换,再重新打包寄出去。服务端收到的可能已经是改过的包裹;服务端寄回来的包裹,同样要经过驿站,才能回到客户端手里。
从技术实现上看,中间层工具有两个关键设计:
- 监听一个本地或者边缘端口,替代真实服务端接收客户端发来的连接。
- 在内部定义一套转发规则,把收到的请求重新发往真实服务端,并把响应原路传回。
这样一来,客户端其实在和中间层工具通信,服务端其实也在和中间层工具通信,而中间层工具同时握有两边的数据流。它不仅能“看”,还能“改”:改请求头、改 query、改 body、改响应状态码、改返回内容,甚至可以什么都不改,只默默录制一份全量流量。这个“截获-读出-改写-转送”的闭环,就是所有中间层工具的共同底层逻辑。
很多刚接触的人会担心:多了一层转发,会不会把性能拖垮?会,但关键看你加在哪一层。本地调试时,多走一个进程,延迟几乎可以忽略。生产环境如果作为统一入口网关,本来就要承担 SSL 卸载、路由、鉴权这些职责,中间层只是把这些逻辑集中到一处,整体收益通常大于性能损耗。只要不做无脑的同步读改写转发,大部分场景都能控制在毫秒级开销内。
1.3 这些场景最值得上中间层工具
接口联调与 Mock。前后端约定好接口结构之后,后端没写完,前端可以先在中间层工具里挂一个 mock 规则,凡是以/api/v2/order开头的请求,直接返回约定的 JSON。前端代码不需要写任何 mock 分支,等后端真的接好之后,删掉规则即可。这个流程我用了很多年,比前端代码里塞 if 分支清爽得多。
故障注入。测试想看超时、断连、HTTP 503 这类异常情况下客户端的表现。中间层工具可以按概率或者按接口路径被动返回错误。比如设置“所有请求,有 10% 概率返回 503”,客户端重试逻辑能不能扛住,一测便知。这种能力在压测和混沌工程里尤其好用。
流量录制与回放。把生产环境的真实请求录下来,脱敏后拿到测试环境重新打一遍,用来验证新版本是否破坏老接口。中间层工具可以做到对流量透明旁录,不修改任何数据,只记录完整请求和响应。回放时再把录制数据按顺序发送到被测系统,比人工造数据真实得多。
统一入口管理。线上系统通常不会让所有服务直接暴露给外部,而是让流量先进一个统一入口,再按路径分发到不同后端服务。入口网关本质上也是一种中间层工具,只是它从“调试辅助”变成了“流量治理底座”,承担路由、限流、熔断、鉴权、审计这些治理能力。后面的章节会单独拆开讲。
2. 中间层工具的主要形态与适用位置
2.1 本地中转调试工具:开发机和真机联调的首选
这一类工具最贴近普通开发者的日常工作:装一台电脑上,配置一个监听端口,把手机或者客户端的网络请求入口指向这台电脑的 IP 和端口,就能在电脑上看到所有经过的请求和响应。
它最典型的场景是抓 App 的包。移动端项目里,你要看线上接口到底返回了什么字段,或者要验证新版 App 请求参数拼得对不对,直接在真机上看日志很费劲,在电脑上挂一个中转工具,然后让手机走电脑这条路,瞬间就能看到全部明文流量。支持 HTTPS 的情况下,工具会生成一张根证书,手机安装并信任后,请求就能被解密查看。
这类工具的配置往往走图形界面:左侧是请求列表,右侧是请求头和响应体,还能按域名、状态码、关键字过滤。我最常用的几个操作是:
- 按域名过滤,只看某个接口域的流量,避免被一堆埋点请求刷屏。
- 断点暂停,让请求停在半路,手动修改参数后再放行。
- 把某个响应保存下来,复制出结构化字段,去做联调断言。
本地中转工具的优势是上手快、交互直观,适合人肉排查。劣势是自动化能力弱,脚本介入不方便。如果要做批量回归,通常需要用第二种形态。
2.2 脚本化拦截改写工具:适合自动化测试与故障演练
这一类形态把中间层逻辑写成可编程的服务,开发者用代码定义“请求进来做什么、响应回来做什么”。它和图形化工具的区别有点像“手动挡和自动挡”:图形工具适合人盯着看,脚本工具适合机器批量跑。
脚本化中间层最常见的做法是一个 Python 进程,监听某个端口,收到请求后进入一个回调函数。回调函数可以改写路径、改写 Header、改写 Body,也可以把请求转发到任意后端,再对响应做断言和记录。因为它本质上是一个普通服务,所以很容易融入自动化测试框架:跑用例之前启动中间层,跑完用例之后读取中间层记录的数据,断言某个请求是否按预期发出,这就是“流量断言”。
我在实际测试工程里最常用它做三件事:
- 给被测系统构造特殊请求,比如伪造一个超长 Token、一个非法枚举值。
- 模拟下游依赖故障,比如让某个接口返回固定的 500 响应,观察被测系统有没有正确降级。
- 定期录制回归流量,把真实请求按时间顺序回放,比对响应结构是否发生变化。
脚本化的门槛比图形工具高一点,但胜在可控性和可复用性。一个企业级测试平台里,埋一个脚本化中间层作为测试伴侣,能让很多以前需要手动造数据的工作变成自动执行。
2.3 生产入口网关工具:适合线上流量调度与管理
如果说本地调试工具是“临时插一段”,那生产入口网关就是“长期长在链路里”。这类工具平时不会只做转发,而是会做更多治理动作:校验身份、控制速率、熔断降级、路由分流、记录审计日志。
最常见的落地形态是 Nginx、OpenResty、Enovy 这类高并发服务。它们通常部署在服务集群的最前面,所有外部请求先打到这个入口,再由入口转给内部的具体服务。它和前面两种中间层工具的差别在于:
- 它面对的是海量并发,不能每个请求都做复杂脚本逻辑。
- 它要做高可用设计,不能机器一挂流量全断。
- 它对协议的支持更全面,除了 HTTP,还要支持 gRPC、WebSocket、TCP/UDP 转发等。
生产入口网关有一个非常核心的优势:全链路可见。因为所有流量都从同一个口子进出,做日志审计、安全过滤、灰度发布都非常方便。比如新版本只放行 5% 的流量,就在入口按用户 ID 取模;突发流量来了,可以每秒只放行 2000 个请求,其余直接拒绝。这些都是入口网关这种“长期中间层”才能做的事。
2.4 中间层工具对比速查表
| 形态 | 工作位置 | 核心能力 | 典型用途 | 适用人群 |
|---|---|---|---|---|
| 本地中转调试工具 | 开发机、局域网 | 可视化查看、改包、HTTPS 解密 | 前后端联调、真机抓包 | 开发、测试 |
| 脚本化拦截改写工具 | 测试环境、CI 环境 | 编程式改写、流量断言、故障注入 | 自动化回归、故障演练 | 测试开发、QA |
| 生产入口网关工具 | 生产集群入口 | 路由、限流、鉴权、灰度、日志 | 线上流量管理、服务治理 | 运维、后端 |
选哪种形态,不取决于工具本身孰优孰劣,只取决于你处在哪个阶段。人肉排查一天几次的,用本地调试工具最有效率;要跑几千个自动化用例的,脚本化其实才是常态;要管线上数万 QPS 的,入口网关跑不掉。
3. 选型必须想清楚的四个问题
3.1 工作层级:透明转发还是应用层感知
中间层工具有一层很关键的区分:它是工作在传输层,还是工作在应用层?
传输层形态,比如用 iptables 做的端口转发,它只负责把 TCP 数据原样搬到另一个目标,不关心里面是 HTTP 还是 MySQL 协议。优点是性能高、兼容性好,几乎所有协议都能转。缺点是“看不见内容”,改不了请求,也做不了更细的断言。
应用层形态则完全相反。它按 HTTP 协议解析请求行、请求头、请求体,甚至能解析 WebSocket 帧、gRPC 消息。看得懂内容,才谈得上按路径路由、按字段改写、按状态码 mock。绝大多数调试场景需要的是应用层感知。
选型建议很直接:如果只是把端口从 A 机器转到 B 机器,传输层就够了;如果你需要看到 URL、Header、Body,或者要在链路上加工数据,请直接选应用层工具。我曾经图省事用传输层转发做了一个临时联调环境,结果前端问“为什么请求没带 Cookie”时,我根本没法在中间层确认,只能重新搭应用层服务,多花了一天时间。
3.2 数据可见与改写能力:只读、可写、可编程
不同工具对数据的干预深度差别非常大。只读工具负责记录请求和响应,不改任何内容,适合流量录制、审计分析。可写工具允许人工或者规则去改请求头、请求体、响应码和响应体,适合 mock 和故障模拟。可编程工具则在可写的基础上开放函数回调,让用户用代码定义任意复杂度的处理逻辑。
这三个级别不是堆叠关系,而是适用场景不同。只读最安全,知道它不会惹祸,适合放在生产环境旁路观察;可写要谨慎,规则写错会直接影响调用方,适合在测试环境用;可编程最灵活,但也最容易出错,我见过有人在中转回调里写了个死循环,直接把整个联调环境拖挂。非必要不上复杂逻辑,这个原则在中间层工具里同样适用。
提到录制流量时,有一点必须时刻记住:真实流量里往往包含用户手机号、Token、Cookie、设备指纹,甚至身份证号。任何录制工具都要具备脱敏能力,至少把 Header 中的 Authorization 和请求体里的敏感字段打码之后再落盘。这不是可选项,是合规红线。
3.3 证书信任与 HTTPS 解密处理
很多人在 HTTPS 环境下用中间层工具失败,核心卡在证书信任链路。正常情况下,客户端收到服务端的证书,会用系统内置的根证书去验证。中间层工具想让客户端“信任自己”,就必须让自己生成的一张根证书被客户端系统信任。
工作流程大概是这样的:
- 中间层工具首次启动时,生成一张本地根证书和一个配套私钥。
- 用户把这张根证书安装到手机或电脑的系统信任区。
- 当客户端请求目标服务时,中间层工具动态地为这个目标签发一张临时证书。
- 客户端验证临时证书时,向上信任到中间层工具的根证书,验证通过,于是客户端以为自己在和真实服务端通信。
- 中间层工具同时与真实服务端建立另一条 HTTPS 连接,解密两边流量,从而看到明文。
需要注意,越先进的工具对证书校验的模拟越完整,但前提是“客户端愿意信任”。这里有两个最常见的坑:
- 只安装证书,没在系统设置里打开“完全信任”,App 内 HTTPS 请求还是会失败。
- 部分 App 自己实现了证书校验,直接把非系统证书的 HTTPS 请求当作非法连接拒绝掉。
解决办法不是去逆这个 App,而是让开发同事给测试包加一个调试开关,绕过证书校验。硬破解证书固定属于逆向范畴,容易踩法律风险,也容易被安全团队标记。
3.4 性能、并发与可维护性
中间层工具是插在数据通路上的设备,它的性能直接决定了体验。选型时至少要问四个问题:
- 单进程能扛多少并发连接?
- 请求体很大的时候,是流式转发还是全部读进内存?
- 长时间连续运行会不会内存泄漏、文件句柄泄露?
- 配置和规则的变更,是否需要重启才能生效?
前两个问题决定它能支撑多大的压力,后两个问题决定运维它有多累。我在本地调试工具上踩过内存溢出的坑:录制一个几百 MB 的下载请求,工具默认把响应体完整读入内存,结果界面直接卡死,电脑风扇狂转。后来改成“只保留响应头,响应体落盘再分析”,问题才解决。
生产级入口网关对可维护性的要求更高。配置变更最好支持热加载,日志要能按小时滚动,健康检查要自动剔除异常节点。如果一个中间层工具动一次配置要重启十秒,那你每个发布窗口都会变得特别痛苦。选型时先问清楚这些问题,后面才不会返工。
4. 实操:半小时搭一个最小可用的请求转发调试服务
4.1 准备工作
想真正理解中间层工具的运转逻辑,强烈建议你别光看文档,自己搭一个最小版本试试。这里我用 Python 实现一个最简请求转发服务,全程用标准库和requests,你只需要准备:
- 一台可以跑 Python 3 的开发机。
- 一个真实的后端服务,可以是本机任意接口,比如
http://127.0.0.1:9000。 - 一个 HTTP 客户端工具,比如 curl、Postman,或者手机 App。
我先说明局限:这个最小服务只处理 HTTP 明文,不会做 HTTPS 解密,也不会上生产。它的意义是让你理解“截获-改写-转送”这条链路是怎么串起来的,理解了之后再用图形工具或生产网关就很简单。
4.2 写出最小转发服务
把下面代码保存为relay.py:
from http.server import HTTPServer, BaseHTTPRequestHandler import requests import sys UPSTREAM = "http://127.0.0.1:9000" class RelayHandler(BaseHTTPRequestHandler): def _relay(self, method): content_length = int(self.headers.get("Content-Length", 0) or 0) if content_length: body = self.rfile.read(content_length) else: body = b"" print(f"[relay] {method} {self.path} body={body[:200]}") headers = {key: value for key, value in self.headers.items()} resp = requests.request( method, UPSTREAM + self.path, data=body or None, headers=headers, timeout=30, ) self.send_response(resp.status_code) for key, value in resp.headers.items(): self.send_header(key, value) self.end_headers() self.wfile.write(resp.content) do_GET = lambda self: self._relay("GET") do_POST = lambda self: self._relay("POST") do_PUT = lambda self: self._relay("PUT") do_DELETE = lambda self: self._relay("DELETE") if __name__ == "__main__": port = int(sys.argv[1]) if len(sys.argv) > 1 else 8888 server = HTTPServer(("0.0.0.0", port), RelayHandler) print(f"listen on {port}") server.serve_forever()启动前先启动后端服务,比如用另一个终端跑python3 -m http.server 9000。然后启动转发服务:
python3 relay.py 8888这时候,如果你这样请求:
curl http://127.0.0.1:8888/some/path观察转发服务输出,能看到它既打印了[relay] GET /some/path,又把请求转发到了http://127.0.0.1:9000/some/path。先跑通这个链路,后面所有问题都好解决。
4.3 加入断点改包能力
上面这个转发服务还只是个透明管道。加上断点改包能力,你可以在请求进入时修改内容。最简单的做法是在_relay里加入一段自定义逻辑,这里我用一个环境变量控制是否开启“故障注入”:
import os FAULT_INJECT = os.environ.get("FAULT_INJECT", "0") == "1" def _relay(self, method): content_length = int(self.headers.get("Content-Length", 0) or 0) body = self.rfile.read(content_length) if content_length else b"" if FAULT_INJECT and self.path.startswith("/api"): print("[relay] inject 503 error") self.send_response(503) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(b'{"error":"injected"}') return headers = {key: value for key, value in self.headers.items()} if FAULT_INJECT: headers["X-Relay-Modified"] = "True" resp = requests.request(method, UPSTREAM + self.path, data=body or None, headers=headers, timeout=30) self.send_response(resp.status_code) ...运行:
FAULT_INJECT=1 python3 relay.py 8888然后请求/api/test,你会直接收到一个 503,根本没有传给后端。这就是故障注入的最小实现。你完全可以把这段逻辑改成按概率生效、按请求参数改写、按 header 判断放行,几乎任何规则都能塞进去。
这次改动虽然简单,但足以说明中间层与直连的核心差异:你能在数据流中间“插一脚”,让本来不会出错的地方出现你想要的状态。这个能力在测试里价值极高。
4.4 真机联调关键步骤
如果你的目标不是 curl,而是手机 App,那要多做三步配置。
第一步,让手机和电脑连同一个局域网,也就是同一个 Wi-Fi。手机通过路由器和电脑通信,才能访问到电脑上的转发服务端口。
第二步,在手机的网络设置里,把“当前 Wi-Fi 的手动请求入口”配成电脑的局域网 IP 和转发服务端口。比如电脑 IP 是192.168.1.100,端口是8888,就在手机里填192.168.1.100:8888。这样手机发出的 HTTP 请求先进你的电脑,再由电脑转给目标服务。
第三步,如果是 HTTPS 请求,你需要在手机上安装并信任前面提到的根证书,同时确认系统里打开“完全信任”开关。Android 和 iOS 的位置都不一样,而且不同系统版本差异很大,这里最稳妥的办法是以你所用工具的最新官方文档为准。别嫌这一步麻烦,装好之后,你就能看到 App 里所有请求的明文结构,调试效率立马上一个台阶。
工具侧再看一眼,你已经完成了三件事:请求从手机到你电脑,再由电脑转发到真实服务端;响应原路返回;中间层在全程可见可改。这就是联调环境最基础的形态。
4.5 从小工具到可复用调试平台
自己写的最小转发服务跑通之后,你大概率会想用它做更多事:加一个规则引擎、加保存录制、加多后端路由。我在实际工作中就是这么一步步走过来的。第一次是给一个 App 项目做了线上抓包,第二次加了一个 mock 规则,第三次加了流量回放,最后这个小小的转发服务变成了团队里的“接口调试中台”,每天支撑几十个测试用例。
但也要提醒自己:不要把小工具无限扩张。小工具的价值在于可解释、可修改,一旦你想让它支持生产级并发、高可用、配置热加载,工程量会迅速膨胀。真到了那一步,建议直接转用成熟的入口网关方案,别重复造轮子。小工具当台阶,大工具当底座,这是我在中间层工具实践里最大的体会。
5. 常见问题与排查经验实录
5.1 请求发不出去?按这五个步骤排查
请求发不出去是高频故障,很多新人第一反应是“工具坏了”。其实八成是链路配置问题,按顺序排查:
- 端口是否监听成功。在电脑上执行
netstat -an | grep 8888,看有没有LISTEN状态。 - 防火墙是否拦截。开发机经常开着系统防火墙,外部设备访问特定端口前要确认放行。
- 局域网 IP 是否可达。在手机浏览器访问
http://电脑IP:8888/,能打开说明网络路径通。 - 上游服务是否启动。直接 curl 一下真实后端地址,确认后端没有挂。
- 客户端是否真的走了中间层。在转发服务的控制台看有没有收到请求日志,没收到说明设备上的请求入口没配好。
这五步走完,90% 的“发不出去”都能定位。剩下的 10%,通常和系统代理环境变量、DNS 缓存、App 自带的直连逻辑有关,需要逐层看日志。
5.2 HTTPS 解密后还是一堆乱码
装好证书后还是看到一堆二进制,常见原因有三个。第一个是请求本身不是 HTTP 协议,可能是 WebSocket 升级或者 gRPC,普通 HTTP 面板没解析成可读文本,但原始帧其实是正常的。第二个是证书信任没生效,尤其是 iOS 只安装没开“完全信任”时,App 内连接直接失败,界面显示一堆连接错误。第三个是你看到的是压缩内容,比如响应体用了 gzip 或 brotli,工具没有自动解压。
解决方法也很直接:先过滤域名,确认目标请求确实经过了你的工具;再检查工具面板上的协议标识;最后确认证书信任开关。如果这些都对,直接看 curl 是否成功,再用工具自带的“导出原始请求”功能分析。
5.3 响应被截断或内容重复
有一次我搭的转发服务返回的响应一会多一段、一会少一段,查了半天才发现问题出在Content-Length。转发时我手工构造了响应,却忘了根据改写后的 body 重新计算长度,导致客户端按照旧长度读取,出现多读或者少读。用标准库写转发服务时,很容易踩这个坑。
另一个常见原因是响应的Transfer-Encoding: chunked。如果你的中间层把分块编码的响应原样转发,但客户端不支持,就会出现内容对不上。最省事的做法是在转发时去掉分块编码,缓存完整响应体后,重新设置Content-Length。这个改动虽然增加一点内存开销,但能避免一堆边界问题。小工具阶段随手处理即可,生产入口网关通常已经封装好了这些细节。
5.4 并发一高就大量超时
脚本化转发服务的性能瓶颈通常不在网络,而在“读完整包再转发”的模式。你每接收一个请求就要把整个 body 读进内存,再同步发到上游,同时只能处理有限并发。一旦上游响应慢,连接就堆积,新的请求全部排队,表现就是大量超时。
解决办法有三个方向:
- 增加连接池复用。把 HTTP 客户端改成全局复用的连接池,避免每次请求都重新握手,能省一大笔开销。
- 开启异步处理。用异步方式同时处理多个请求,而不是一个接一个阻塞。
- 限制大包体。超过阈值直接走旁路,或者只做头部转发,不做 body 缓存。
我曾在压测环境用最小同步转发服务模拟 500 并发,结果撑了不到一分钟就卡死了。改成异步模式后同样场景轻松过了两万请求。这个对比让我深刻体会到,中间层工具的性能上限往往取决于实现方式,而不是机器性能。
5.5 常见问题速查表
| 现象 | 常见原因 | 排查动作 |
|---|---|---|
| 请求不到中间层 | 防火墙、端口、IP 配置问题 | 先 ping IP,再抓端口监听 |
| HTTPS 失败 | 证书未信任 / 未开完全信任 | 重装证书,检查系统信任设置 |
| 响应中文乱码 | 字符集 / 压缩协议未解码 | 检查响应头 charset,开启自动解压 |
| 响应内容不对 | Content-Length 未更新 | 改写后重新计算响应长度 |
| 并发一高就超时 | 同步阻塞式转发 | 改连接池,改异步处理 |
| App 不走中间层 | 请求入口未配置 / App 实现直连 | 控制台看有无对应请求日志 |
5.6 几则现场教训
第一个教训是开通“改包”能力时一定要设白名单。我在测试环境放了一个 mock 规则,本来只想拦/mock路径,却因为正则写得太宽,把真实下单接口也拦了,直接导致联调环境订单服务不可用。中间层工具越强大,越要有“规则只在明确指定路径生效”的习惯。
第二个教训是录制流量后千万不要直接存明文。曾经有位同事把录制好的流量包发到协作群里,里面含有一个用户的手机号和登录 Token,技术群里瞬间变成安全事故。从那之后,我们的所有录制工具都默认脱敏,Authorization字段强制打码,不在代码里留任何明文打点。
第三个教训是中间层工具本身的日志要控制。排查问题时开着详细日志是好事,但如果线上长期开启全量请求体日志,磁盘会把很快涨满。我建议日志按“采样 + 脱敏 + 滚动保留”三原则来做,平时只记录请求行、状态码和耗时,仅在需要深入排查时才打开请求体记录。
最后再分享一个小技巧
做中间层工具这么多年,我越来越觉得它不是一个“要不要用”的问题,而是“放在哪一层用、在哪一层停”的问题。小到本地断点改包,大到生产入口网关,核心思想都一样:在数据通路上获得一个可观测、可干预的控制点。很多时候你不需要什么高级功能,一个能记录请求、能按规则转发的脚手架,就能解决一大半调试痛点。
如果今天你只能带走一个经验,我希望是:不要在链路完全黑盒的情况下盲目改代码。先在客户端和服务端中间插一道中间层,看清流量长什么样子,再决定怎么改。这个动作看起来多了一步,实际省下的时间却是数倍计。这个习惯,值得你从下一个问题开始养成。