nginx a client request body is buffered to a temporary file 错误解决

错误信息

a client request body is buffered to a temporary file /tmp/nginx/client-body/0000602356

含义:客户端 POST 的请求体(body)太大,超过了 Nginx 的内存缓冲区大小,Nginx 就把 body 落盘到 /tmp/nginx/client-body/ 下的临时文件,再转发给后端。

这不是错误,但会带来:

  • 额外磁盘 IO(尤其 router pod /tmp 在容器文件系统/emptyDir 上)
  • 延迟抖动(高并发时明显)
  • /tmp 空间不够时可能演变成 413/499/502 等问题

access log 里这些数字内容

比如这一行:

2026-01-19T11:00:01.267271218+08:00 10.233.97.0 - - [19/Jan/2026:03:00:01 +0000] "POST /admin-api/getUserValueList HTTP/1.1" 200 23949 "https://xxx.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0" 12719 0.204 [dev-gateway-server-8080] [] 127.0.0.1:8080 23911 0.204 200 d814da4cbb8343552b169c80910xxxxx

常见 Nginx Ingress 格式里:

1)前缀时间与客户端地址

  • 2026-01-19T11:00:01.267271218+08:00
    日志打印时间(本地时区 +08:00)

  • 10.233.97.0 - -

    • 10.233.97.0:客户端 IP(在集群内通常是某个 Pod / 代理的 IP)
    • 后面两个 -:一般对应 remote_user 等未使用字段

2)Nginx 访问时间(UTC 格式)

  • [19/Jan/2026:03:00:01 +0000]
    Nginx access log 的时间(UTC,+0000)。
    看到它和前缀的 +08:00 对应得上:11:00(+8) = 03:00(UTC)

3)请求行(Request)

  • "POST /admin-api/getUserValueList HTTP/1.1"
    方法 + 路径 + 协议版本

4)返回码与响应大小

  • 200:Nginx 最终返回给客户端的 HTTP 状态码
  • 23949:响应体大小(bytes,通常是 body bytes)

5)Referer 与 User-Agent

  • "https://xxx.com/":Referer(请求从哪个页面发起)
  • "Mozilla/5.0 ... Edg/135.0.0.0":浏览器 UA

6)request_length 与 request_time

  • 12719request_length(请求总长度,bytes)
    = 请求行 + header + body 的总字节数
    这个值偏大通常意味着 POST body 较大(或 header 很多)

  • 0.204request_time(秒)
    Nginx 从接收请求到把响应完整返回给客户端的总耗时

7)upstream 相关(反向代理到后端)

  • [dev-gateway-server-8080]:上游 upstream 名称(配置的 upstream/服务名)

  • []:一般是一些可选字段(如 upstream cache 状态、request id、grpc status 等),这里为空

  • 127.0.0.1:8080upstream_addr
    实际转发到的后端地址。
    这里是 127.0.0.1:8080,说明 Nginx 可能和后端在同 Pod/同容器网段(或有 sidecar/本地转发)。

  • 23911upstream_response_length(bytes)
    上游返回的响应大小(通常与 23949 接近,差值可能来自 header/编码/日志口径不同)

  • 0.204upstream_response_time(秒)
    Nginx 等上游返回(并读取完响应)的时间
    这里和 request_time 一样,说明:

    • Nginx 自己处理开销很小
    • 主要耗时都在上游处理/网络传输
  • 200upstream_status
    上游返回状态码(也可能有多个,用逗号分隔;这里单个 200)


8)最后的长串

  • d814da4cbb8343552b169c80910xxxxx
    多数环境这是 request_id / trace_id(用于链路追踪/日志关联)。
    具体叫法要看你 Nginx 的 log_format 怎么配置(常见来自 $request_id 或自定义 header 如 X-Request-Id)。

解决办法

方案 A:只针对这个接口所在的 Ingress 调大缓冲/关闭请求缓冲

如果 kubesphere-router 是基于 nginx-ingress(KubeSphere 常见),可以在 Ingress 上加 annotation:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/client-body-buffer-size: "1024k"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/proxy-request-buffering: "off"

解释:

  • client-body-buffer-size:提高“内存里装 body”的大小,减少落盘
  • proxy-body-size:避免大请求直接 413
  • proxy-request-buffering: off:尽量不要把请求体完整缓冲后再转发(对大 POST 更友好)

方案 B:全局调大 router 的 Nginx 参数(影响所有路由)

如果 router 全局都不落盘,可以改 kubesphere-router 对应的 ConfigMap(名称因集群不同,常见是 ingress-nginx-controller / kubesphere-router 相关 cm),加入类似:

  • client-body-buffer-size: 64k
  • proxy-body-size: 10m
  • (必要时)client-body-temp-path 指向一个有足够空间的挂载

这会影响所有业务,改之前要考虑内存占用。

posted @ 2026-01-19 11:13  zhubayi  阅读(0)  评论(0)    收藏  举报