专栏首页程序员升级之路nginx upstream header过大是啥情况

nginx upstream header过大是啥情况

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

[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的内容过长。

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

fastcgi_buffer_size 16k; 
fastcgi_buffers 8 128k;

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

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

 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结构来管理缓冲区:

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注册不上问题排查

本文分享自微信公众号 - 程序员升级之路(gh_1fab42db66cb),作者:刘江华

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Raft算法之集群成员变化篇

    集群成员变化是一个常见操作,主要是增加、删除节点,主要的场景有升级、服务器老化等,当然如果我们对服务的SLA没太大要求,直接关闭集群是最简单的办法。但如果要保证...

    心平气和
  • 线上故障处理实践

    最近公司一个系统发生线上故障,系统架构为C/S的,客户端是APP;系统的功能有:联系人、短信、通话记录等,每个业务都有备份、恢复的功能,即用户可以在APP内备份...

    心平气和
  • 从RabbitMQ Channel设计看连接复用

    今天公司有同事在做RabbitMQ的分享的时候,讲到了Connection和Channel的设计,有同学有疑惑,为什么不用连接池实现,而要通过Channel的方...

    心平气和
  • CentOS 8.1下搭建LEMP(Linux+Nginx+MySQL+PHP)环境(教程详解)

    LEMP是一个软件堆栈,包含一组免费的开源工具,这些工具用于为高流量和动态网站提供动力。 LEMP是Linux,Nginx(发音为Engine X),Maria...

    砸漏
  • 解析SDN与实际应用的距离

    目前很多SDN(Software Defined Network,软件定义网络)的解决方案还主要集中在高校、ONF组织、运营商及设备厂商中进行探索研究,多停留在...

    SDNLAB
  • Redis入坟(一)redis的前世今生、redis基础及存储结构源码讲解

    08 年的时候有一个意大利西西里岛的小伙子,笔名 antirez,创建了一个访客信息网站 LLOOGG.COM。有的时候我们需要知道网站的访问情况,比如访客的 ...

    源码之路
  • 剑指offer - 合并两个排序的链表 - JavaScript

    题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

    心谭博客
  • 利用Intel傲腾存储制定更智能的数据策略

    滴水成河,积水成渊,许多企业今天面临的存储危机其实是数据字节累积的结果。数据的增长表现在三个不同方面:

    冬瓜哥
  • phar反序列化rce

    在Blackhat2018,来自Secarma的安全研究员Sam Thomas讲述了一种攻击PHP应用的新方式,利用这种方法可以在不使用unserialize(...

    安恒网络空间安全讲武堂
  • 让知更鸟主题的分类图标支持二级分类

    今天,突然想启用知更鸟主题的分类图标功能,之前是怕影响速度,现在开了静态缓存,安心了一点。 参照鸟哥的方法在主题选项里面开启后,发现图片的超链接打不开!检查后发...

    张戈

扫码关注云+社区

领取腾讯云代金券