记一次nginx因client_header_buffer_size和proxy_buffers配置导致的问题排查

1、问题背景:
前端需要进行图片上传,在一次版本优化后,根据客户要求取消了图片压缩,导致上传接口请求header徒增,nginx报错信息如下:
[warn] 60937#0: *34319 an upstream response is buffered to a temporary file /dev/shm/proxy/0/40/0000000400 while reading upstream,
2、导致的问题原因:
后台nginx配置如下:

client_header_buffer_size       32k;
large_client_header_buffers     4 32k;
proxy_buffer_size               32k;
proxy_buffers                   4 32k;
proxy_busy_buffers_size         64k;

由于header限制配置为32K,超过这个大小会进行拦截,导致nginx转发报错。
3、问题解决:
调整nginx配置

client_header_buffer_size       256k;
large_client_header_buffers     4 256k;
proxy_buffer_size               256k;
proxy_buffers                   16 256k;
proxy_busy_buffers_size         1024k;

重新加载配置
./sbin/nginx -s reload
4、配置详解
通用的 HTTP 请求头相关的配置主要也是大小、超时时间等等。它们都可以配置在 http、server 下面。

client_header_buffer_size
用于设置读取客户端请求头部的缓冲容量。
client_header_buffer_size size;
默认值是 1k ,对于大多数请求,1K的缓冲足矣。但如果请求中含有的cookie很长,或者请求来自WAP的客户端,可能请求头不能放在1K的缓冲中。 如果从请求行,或者某个请求头开始不能完整的放在这块空间中,那么 Nginx 将按照 large_client_header_buffers 指令的配置分配更多更大的缓冲来存放。

proxy_buffers:定义缓冲区的数量和大小,本文设置为 16 个 256KB 的缓冲区。
proxy_buffer_size:设置用于存储响应头的缓冲区大小,这里设置为 1024KB。
proxy_busy_buffers_size:定义在缓冲区繁忙时可以使用的缓冲区大小,通常为 proxy_buffers 总大小的两倍。

这里和请求体不同的是,请求体会往文件里放,但请求头不会,不够了再根据其它配置申请更大的内存。毕竟请求头的内容再大也大不到像需要上传文件的请求体一样。最终它的配置其实不会导致什么影响,因为最终如果不够了它会根据 large_client_header_buffers 的配置进行申请分配,因此,我们紧接着就看看 large_client_header_buffers 的配置。

large_client_header_buffers
这个配置是设置读取客户端请求超大请求的缓冲最大 number(数量) 和每块缓冲的 size(容量) 。

large_client_header_buffers number size;
它的默认值是 4 8k 。条件包括这么几点:

HTTP 请求行的长度不能超过一块缓冲的容量,否则nginx返回错误414 (Request-URI Too Large)到客户端。

每个请求头的长度也不能超过一块缓冲的容量,否则nginx返回错误400 (Bad Request)到客户端。

(请求行+请求头) 的大小不能超过 32k(4 * 8k) 。

5、优化后的nginx配置(仅参考使用,根据不同环境调整):

http
{
include mime.types;
default_type application/octet-stream;
server_tokens off;
log_format main '$http_x_forwarded_for | $time_local | $status | $body_bytes_sent | $gzip_ratio | '
'$request_method | $scheme | $server_protocol | $server_name | $server_port | '
'$request_uri | $request_time | $content_length | $http_referer | $http_user_agent | '
'$remote_addr | $remote_port | $remote_user | $http_cookie | $hostname | '
'$upstream_status | $upstream_addr | $upstream_http_host | $upstream_response_time';

    #charset                        utf-8;
    server_names_hash_bucket_size   128;
    client_header_buffer_size       256k;
    large_client_header_buffers     4 256k;
    client_max_body_size            300m;
    sendfile                        on;
    tcp_nopush                      on;
    keepalive_timeout               180s;
    tcp_nodelay                     on;
    client_body_buffer_size         2048k;
    fastcgi_intercept_errors        on;
    proxy_connect_timeout           90;
    proxy_read_timeout              180;
    proxy_send_timeout              180;
    proxy_buffer_size               256k;
    proxy_buffers                   16 256k;
    proxy_busy_buffers_size         1024k;
    proxy_temp_file_write_size      256k;
    proxy_intercept_errors          on;
    server_name_in_redirect         off;
    proxy_hide_header       X-Powered-By;
    proxy_ignore_client_abort on;
    gzip                            on;
    gzip_min_length                 100;
    gzip_buffers                    4 256k;
    gzip_http_version               1.0;
    gzip_comp_level                 9;
    gzip_types                      text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
    gzip_vary                       on;
    include domains/*;

}

下面整理了nginx日志中常见的 error 日志:
1.”upstream prematurely(过早的) closed connection”

请求uri的时候出现的异常,是由于upstream还未返回应答给用户时用户断掉连接造成的,对系统没有影响,可以忽略

2.”recv() failed (104: Connection reset by peer)”

(1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;

(2)客户关掉了浏览器,而服务器还在给客户端发送数据;

(3)浏览器端按了Stop
3.”(111: Connection refused) while connecting to upstream”

用户在连接时,若遇到后端upstream挂掉或者不通,会收到该错误

4.”(111: Connection refused) while reading response header from upstream”

用户在连接成功后读取数据时,若遇到后端upstream挂掉或者不通,会收到该错误

5.”(111: Connection refused) while sending request to upstream”

Nginx和upstream连接成功后发送数据时,若遇到后端upstream挂掉或者不通,会收到该错误

6.”(110: Connection timed out) while connecting to upstream”

nginx连接后面的upstream时超时

7.”(110: Connection timed out) while reading upstream”

nginx读取来自upstream的响应时超时

8.”(110: Connection timed out) while reading response header from upstream”

nginx读取来自upstream的响应头时超时

9.”(110: Connection timed out) while reading upstream”

nginx读取来自upstream的响应时超时

10.”(104: Connection reset by peer) while connecting to upstream”

upstream发送了RST,将连接重置

11.”upstream sent invalid header while reading response header from upstream”

upstream发送的响应头无效

12.”upstream sent no valid HTTP/1.0 header while reading response header from upstream”

upstream发送的响应头无效

13.”client intended to send too large body”

用于设置允许接受的客户端请求内容的最大值,默认值是1M,client发送的body超过了设置值

14.”reopening logs”

用户发送kill -USR1命令

15.”gracefully shutting down”

用户发送kill -WINCH命令

16.”no servers are inside upstream”

upstream下未配置server

17.”no live upstreams while connecting to upstream”

upstream下的server全都挂了

18.”SSL_do_handshake() failed”

SSL握手失败

19.”ngx_slab_alloc() failed: no memory in SSL session shared cache”

ssl_session_cache大小不够等原因造成

20.”could not add new SSL session to the session cache while SSL handshaking”

ssl_session_cache大小不够等原因造成

posted @ 2025-03-28 10:09  小白不怕黑  阅读(734)  评论(0)    收藏  举报