Kong "a client request body is buffered to a temporary file" 分析

4,041 阅读3分钟

背景

升级Kong的版本,搭建了新的线上环境,切了小流量进行了一下测试。error.log中不断刷warn日志:a client request body is buffered to a temporary file。通过上网搜索把问题定位在Nginx的client_max_body_sizeclient_body_buffer_size的两个配置上。

2019/06/24 18:59:42 [warn] 20447#0: *5393147 a client request body is buffered to a temporary file /usr/local/kong/client_body_temp/0000000573, client: "", server: kong, request: "PUT /car/", host: ""

kong.conf

#client_max_body_size = 0        # Defines the maximum request body size allowed
                                 # by requests proxied by Kong, specified in
                                 # the Content-Length request header. If a
                                 # request exceeds this limit, Kong will
                                 # respond with a 413 (Request Entity Too
                                 # Large). Setting this value to 0 disables
                                 # checking the request body size.

# Note: see http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
# for further description of this parameter. Numeric values may be suffixed
# with 'k' or 'm' to denote limits in terms of kilobytes or megabytes.

#client_body_buffer_size = 8k    # Defines the buffer size for reading the
                                 # request body. If the client request body is
                                 # larger than this value, the body will be
                                 # buffered to disk. Note that when the body is
                                 # buffered to disk Kong plugins that access or
                                 # manipulate the request body may not work, so
                                 # it is advisable to set this value as high as
                                 # possible (e.g., set it as high as
                                 # `client_max_body_size` to force request
                                 # bodies to be kept in memory). Do note that
                                 # high-concurrency environments will require
                                 # significant memory allocations to process
                                 # many concurrent large request bodies.

# Note: see http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size
# for further description of this parameter. Numeric values may be suffixed
# with 'k' or 'm' to denote limits in terms of kilobytes or megabytes.

kong.conf的配置大概了解到配置主要的作用:

  • client_max_body_size:被kong代理的请求体最大的size。如果请求体的大小超过阈值,会返回413。该值为0时表示无限制。

  • client_body_buffer_size:用于读请求体的buffer大小。如果客户端段请求的请求体超过阈值,请求体的内容会被缓存到磁盘上。一旦请求体被缓存到磁盘上那么对于kong的插件对请求的维护和操作有可能会失败,kong处理请求的速断会变慢。

那么可以从上面的解释大哥猜测是warn日志产生的原因:client_body_buffer_size配置过小,client端过来的请求超过的阈值被请求体被写到了磁盘上 /usr/local/kong/client_body_temp/0000000573。(由于权限不过看不文件的内容)

深入

再结合Nginx官方文档,深入理解一下Nginx buffer相关的配置。

  • client_body_in_single_buffer:决定Nginx是否存储整个请求体到文件。一般用于debuging或是Nginx的module中。当该值被设置为 on 是,临时的文件将不会被在请求处理完后删除。
  • client_header_buffer_size:与 client_body_buffer_size类似,是请求头的缓存。通过 large_client_header_buffers 配置。

后续

然后修改了Kong的配置也warn日志还是刷的飞起。继续定位问题。

This is Nginx's behavior, not Kong. See nginx_http_proxy_module's directives and how to configure them . See the proxy_max_temp_file_size and proxy_buffers in particular.

  • proxy_buffer_size:用于缓冲响应头。
  • proxy_buffers:(Syntax: proxy_buffers number size) 设置用于缓冲从proxied server返回的响应体的buffer的个数和每个连接的buffer大小。
  • proxy_busy_buffers_size:忙时 buffer 的最大值。当Nginx开启了来自proxied服务器响应buffer,由于受到buffer大小的限制,一个响应在没有被完全读取的时候就被发送出去了。同时剩余的buffer仍在接收响应,如果需要,一部分内容将缓存到临时文件。

"proxy_busy_buffers_size" must be equal to or greater than the maximum of the value of "proxy_buffer_size" and one of the "proxy_buffers"
"proxy_busy_buffers_size" must be less than the size of all "proxy_buffers" minus one buffer

  • proxy_max_temp_file_size:当Nginx开启了来自proxied服务器响应buffer,并且buffer的大小超过了proxy_buffer_size设置的阈值,响应体的一部分会被存储的临时文件中。一次写入临时文件的数据由proxy_max_temp_file_size设置。

然后在老的Kong找到关于proxy_buffer相关的配置

    # Proxy Settings
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;