nginx upstream header过大是啥情况

2020-09-29 14:49:21 浏览数 (1)

公司一项目采用LNMP架构,最近老是报502,Nginx错误日志如下:

代码语言:javascript复制
[error] 7649#0: *60873458 upstream sent too big header while reading response header from upstream, client: XXX, server: XXX, request: "GET /xx HTTP/1.1",

因为涉及到一些敏感信息,所以一些关键信息去除了,但这不影响问题的分析。

从字面理解应该是Upstream返回的header头超出限制了 ,这里大概脑补下FastCgi协议,Nginx和PhpFpm是通过这个协议进行数据传输的,其中Nginx和后端所有Upstream交互都是分两步的,第一步是处理头,第二步是处理body,每个协议实现自己的部分。

FastCgi协议这里不详述,在本案例中,头部分相关于后端写回的http头太大了,具体是哪部分大,一般来说是Cookiem的内容过长。

百度了一下,说要调整缓冲区大小,

代码语言:javascript复制
fastcgi_buffer_size 16k; 
fastcgi_buffers 8 128k;

其中fastcgi_buffer_size默认是4K,在这个案例中,因为后端返回的Cookie和其它Http头信息超出4K了,所以报错,这里调整为16K,问题解决。

具体可以看下Nginx源码中处理FastCgi头的函数ngx_http_upstream_process_header:

代码语言:javascript复制
 if (rc == NGX_AGAIN) {
            if (u->buffer.last == u->buffer.end) {
                ngx_log_error(NGX_LOG_ERR, c->log, 0,
                              "upstream sent too big header");
                ngx_http_upstream_next(r, u,                                       NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);                return;
            }            continue;
        }

这里会判断last是否等于end,其中u->buffer为Nginx和后端Upstream交互的缓冲区,Nginx通过ngx_buf结构来管理缓冲区:

代码语言:javascript复制
struct ngx_buf_s {
    u_char          *pos;    u_char          *last;    off_t            file_pos;
    off_t            file_last;
    u_char          *start;         /* start of buffer */
    u_char          *end;           /* end of buffer */
    ngx_buf_tag_t    tag;
    ngx_file_t      *file;
    ngx_buf_t       *shadow;
  ……

其中start是缓冲的开始部分,end是结束部分,这是系统分配下来的,实际用的时候是将数据读到缓冲区里,并增加last部分,还有个pos表示应用处理的部分。

打个比方,我申请了1000的内存,开始地址为 1000,结束为1999(当然实际地址不可能这么小,这些是留给OS的,这里只是便于说明问题),那刚开始start为1000,end为1999,pos和last都为1000;这个时候应用读取后端upstream的头部分,读取了500字节,那last指向1500,post指向0,然后解析upstream的头,转换为内部一些结构,则pos也推进了。

回到上面的情况, 这里判断了last是否指向了end,这种情况下表示这个缓冲区已经用完了,在案例中,因为配的是4K,即表示从upstream中读取的头超出了4K,所以报错。

这个配置是针对每个Upstream的,即如果同时有1000个请求,则占用1000*16K的内存,所以不宜设的过大,这也是Nginx保存内存的一种办法。

Nginx配置不当险酿S0

Skywalking Php注册不上问题排查

0 人点赞