这个坑值得记一笔。Node 服务用 undici 并发 30 路调多模态接口做质检,每张图 base64 后约 6MB,压测时三成请求返回 413 Payload Too Large,单路串行同一批图全部成功。
刚开始盯着「base64 编码让体积膨胀三分之一,压测样本没算这部分」,折腾了半个多小时,排掉了。
原因不止一个,得分开看。Nginx 的 client_max_body_size 还是默认 1MB;并发时请求被合并到同一连接,缓冲区溢出后整包被拒;客户端重试把 413 也重发了,队列越积越深。
单独发一张确认是体积还是并发问题
curl -i -X POST https://api.example.com/v1/vision -H 'Content-Type: application/json' --data-binary @one.json
随后在网关侧把请求体上限调到 20m 并重载
nginx -T | grep client_max_body_size && nginx -s reload
客户端改成先压到 1280 宽再编码
python -c "from PIL import Image;im=Image.open('p.jpg').convert('RGB');im.thumbnail((1280,1280));im.save('p_s.jpg',quality=82)"
压测脚本把并发降到 8 并只对 5xx 重试
python loadtest.py --concurrency 8 --retry-on 502,503,504
别只看报错消失,验证要多做一步。30 路并发跑满五分钟 413 归零,网关日志里请求体最大值低于新上限,P95 延迟没有明显上升。
413 是网关先返回的,应用层日志里往往什么都看不到,排查时先看入口层配置再看业务代码。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
