# 财务管理-结算记录:点「查询」偶发 502(Request failed with status code 502) Status: needs-triage 领域: 支付链路(自动结算与结算记录)+ 管理后台公共 http 客户端 来源: 用户工单「【结算记录】查询报错了 这个是什么问题 现在无法重现」(截图:2026-09-18 页面顶部红色提示 Request failed with status code 502,表格里仍是上一次查询出来的数据) 日期: 2026-09-18 ## 现象 「财务管理 → 结算记录」点「查询」时,页面顶部弹出红色提示 `Request failed with status code 502`。 列表本身已经渲染出数据(说明**上一次**查询是成功的),失败的是**这一次**请求。用户随后重试无法复现。 ## 根因 这个 502 **不是结算记录接口自己返回的**,而是「前端 → 后端」之间代理层的报错:代理向上游发起请求时 连接出错(后端不在监听 / 连接被中途重置),Vite 的代理中间件就固定回一个 **502 + 空 body**。 三处证据: 1. **文案只可能来自这里**:`talent-card-admin/src/api/http.ts:36-38` 的提示是 `error.response?.data?.message || error.message`。后端所有业务异常都会带 JSON `{code, message}`, 只有响应体里没有 `message`(例如代理回的 502 空 body)时才会退化成 axios 兜底文案 `Request failed with status code 502`。 2. **Vite 代理正好是 502 + 空 body**:`talent-card-admin/node_modules/vite/dist/node/chunks/node.js:18674-18681` —— `proxy.on('error', ...) { ... res.writeHead(502, { 'Content-Type': 'text/plain' }).end() }`; 同时终端里会打一行 `http proxy error: /api/...` 加 `err.stack`。 3. **后端代码里没有 502**:`talent-card-server` 的 java 与 resources 全量搜索无 `502`/`Bad Gateway`, 接口出错走的是 Bean Validation / `BusinessException`(JSON 响应),不会产生代理级状态码。 所以「无法重现」是预期的:触发条件是**那一瞬间的连接失败**,常见来源—— - 后端正好在重启(IDEA 里重新运行 / `mvn` 重新编译部署),端口有一段不可连接的空窗; - 代理复用了 Tomcat 已经关掉的 keep-alive 长连接,Vite 侧收到 RST 后直接把这次请求判成 502; - 后端进程被重启/挂起,请求在写响应前连接就断了。 ## 关联的稳定性隐患(同一个接口,值得一并处理) 结算记录这条链路本身很"重",商户一多就更容易撞上上面任何一种超时/重试: - `MerchantSettlementAdminService.settlements(...)` (`talent-card-server/src/main/java/com/talentcard/server/business/admin/MerchantSettlementAdminService.java:68-83`) 是**逐商户串行**调用斗拱结算流水接口:`for (merchant : merchants) settlementRecordGateway.query(...)`, 没有并发、没有超时上限、没有缓存。单次「查询」的成本 = 已进件商户数 × 一次跨公网 HTTPS 往返。 - 当前库里符合条件的商户(`status='approved'` 且 `provider_huifu_id` 非空的每个商户最新一条)是 4 家: `喜望商家 6666000239896857`、`存量商户验证专用 6666000226048687`、`个人进件验证商户 6666001804122`、 `景区服务-卡 6666000242182522`。商户继续变多,整页耗时线性增长。 - 前端 axios 只等 **12 秒**(`talent-card-admin/src/api/http.ts:9` `timeout: 12000`),一旦超过就是 `timeout of 12000ms exceeded`(另一个不同的报错文案),或用户以为"卡住了"而重复点击、放大后端压力。 - 后端**没有文件日志**(`application.yml:164-166` 只配了 `logging.level`,没有 file appender), 所以事后查不到当时的 `Huifu settlement record query failed` / 请求耗时——这也是这次"查无实据"的原因之一。 ## 建议改法(支付链路负责人 / 前端公共部分) 1. 先按现场日志定性:复现时看 **Vite 终端**有没有 `http proxy error: /api/admin/management/merchant-settlement/settlements` (有 = 连接层问题,看 `err.stack` 区分 ECONNREFUSED / ECONNRESET)、**IDEA 控制台**在那个时间点是否在重启。 2. 结算记录接口收敛耗时:商户维度并发查询(或限流并发)+ 单商户调用超时上限 + 结果短时缓存/手动刷新, 让整页耗时不再随商户数线性增长。 3. 后端加文件日志(或至少把通道查询耗时记进日志),下次出现同类问题能直接判断是"慢"还是"断"。 4. 前端错误提示区分"代理/网关错误"与业务错误:对 `502/504/ECONNABORTED` 给出中文提示, 而不是把 axios 的英文兜底文案直接弹给用户。 ## Comments - 2026-09-18:由「其余业务」侧的会话只读排查后归档(按仓库约定,支付链路代码未改动)。 结论:本次 502 是**代理层**的连接失败(后端重启/长连接被重置),不是结算记录接口的业务缺陷; 但该接口「逐商户串行查斗拱 + 前端 12 秒超时 + 无文件日志」让它天然容易出现这类偶发失败,建议一并收敛。