上游从上游读取响应头时发送了太大的头


227

我收到这些错误:

2014/05/24 11:49:06 [错误] 8376#0:* 54031上游发送太大的标头,同时从上游读取响应标头,客户端:107.21.193.210,服务器:aamjanata.com,请求:“ GET / the- gujarat-government /赞助的洗脑历程/%20https:/aamjanata.com/the-brainwash-chronicles-gujarat-government/赞助护脑,%20https:/aamjanata.com/the-brainwash-chronicles-由Gujarat-government赞助,%20https://aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by- gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/ ,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/ aamjanata。com / the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the- gujarat-government /赞助的洗脑历程/%20https:/aamjanata.com/the-brainwash-chronicles-gujarat-government/赞助护脑,%20https:/aamjanata.com/the-brainwash-chronicles-由Gujarat-government赞助,%20https://aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by- gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20https://aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored by-gujarat-government /,%20https:/ aamjanata。com / the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government /,%20https:/aamjanata.com/the- gujarat-government /赞助的洗脑纪事/%20https://aamjanata.com/the-brainwash-chronicles-gujarat-government/赞助的百灵鸟https:/aamjanata.com/the-brainwash-chronicles-由古吉拉特邦政府赞助,%20ht

总是一样。网址重复并以逗号分隔。无法弄清楚是什么原因造成的。有人有主意吗?

更新:另一个错误:

http request count is zero while sending response to client

这是配置。还有其他不相关的内容,但是此部分已添加/编辑

fastcgi_cache_path /var/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;
    # Upstream to abstract backend connection(s) for PHP.
    upstream php {
            #this should match value of "listen" directive in php-fpm pool
            server unix:/var/run/php5-fpm.sock;
    }

然后在服务器块中:设置$ skip_cache 0;

    # POST requests and urls with a query string should always go to PHP
    if ($request_method = POST) {
            set $skip_cache 1;
    }
    if ($query_string != "") {
            set $skip_cache 1;
    }

    # Don't cache uris containing the following segments
    if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $skip_cache 1;
    }

    # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
            set $skip_cache 1;
    }

    location / {
            # This is cool because no php is touched for static content.
            # include the "?$args" part so non-default permalinks doesn't break when using query string
            try_files $uri $uri/ /index.php?$args;
    }


    location ~ \.php$ {
            try_files $uri /index.php;
            include fastcgi_params;
            fastcgi_pass php;
            fastcgi_read_timeout 3000;

            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;

            fastcgi_cache WORDPRESS;
            fastcgi_cache_valid  60m;
    }

    location ~ /purge(/.*) {
        fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
    }`

您的代理配置似乎不正确。您可以共享配置吗?
2014年

你可以尝试添加:fastcgi_buffers 16 16k; fastcgi_buffer_size 32k;
2014年

Answers:


406

将以下内容添加到您的conf文件中

fastcgi_buffers 16 16k; 
fastcgi_buffer_size 32k;

160
当您的回答使我得到正确的答案时,您应展示如何确定正确的缓冲区大小以及为什么如此重要。否则,它是黑暗中的一枪。请参阅此处以获得有关尺寸调整的想法:gist.github.com/magnetikonline/…–
Wes Johnson

4
“ fastcgi_buffer_size 32k;” 仅此一项是行不通的,我需要两行重启NginX。我来这里是因为WordPress插件导致NginX出现502错误。
PJ Brunet

6
如果fast_cgi_buffers没有帮助,请尝试proxy_buffers 以下 @amd给出的答案
icc97 '17

11
请对此答案做任何解释。
埃德森·霍拉西奥

5
它对我有用,我只想补充一下,在ubuntu 16.04中,nginx配置文件位于,/etc/nginx/nginx.conf值应该放在http {...}
Mario

134

如果nginx正在作为代理/反向代理运行

也就是说,对于 ngx_http_proxy_module

除之外fastcgi,该proxy模块还将请求标头保存在临时缓冲区中。

因此,您可能还需要增加proxy_buffer_sizeproxy_buffers,或者完全禁用它(请阅读nginx文档)。

代理缓冲配置示例

http {
  proxy_buffer_size   128k;
  proxy_buffers   4 256k;
  proxy_busy_buffers_size   256k;
}

禁用代理缓冲区的示例(建议用于长轮询服务器)

http {
  proxy_buffering off;
}

有关更多信息:Nginx代理模块文档


8
“ proxy_busy_buffers_size”必须小于所有“ proxy_buffers”的大小减去一个缓冲区
chovy

你是男人!谢谢!首选方法在我的ruby on rails应用程序中起作用
齐尔

可能是一个愚蠢的问题,但是我在返回此错误的服务器前有一个代理。更改缓冲区可以正常工作,但是我在内部计算机上收到了一个新错误。writev() failed (104: Connection reset by peer) while sending to client 这些代理设置是否可以解决该错误,并且会继续使用上游服务器或代理吗?
亚当·帕特森

1
为什么proxy_buffers 4 ...呢?由于默认值似乎是8
adrianTNT

23

upstream sent too big header while reading response header from upstream 是nginx说“我不喜欢自己所见”的通用方式

  1. 您的上游服务器线程崩溃
  2. 上游服务器发回了无效的标头
  3. 从STDERR发送回的通知/警告溢出了缓冲区,并且缓冲区和STDOUT已关闭

3:查看消息上方的错误日志,它是否与消息之前的记录行一起流传输? PHP message: PHP Notice: Undefined index: 循环日志文件中的示例片段:

2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
... // 20 lines of same
PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undef
2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "ta_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Firstname

您可以从底部的第三行中看到缓冲区限制已达到,被破坏,并且下一个线程写入了缓冲区限制。然后,Nginx关闭连接,并将502返回给客户端。

2:记录每个请求发送的所有标头,对其进行检查并确保它们符合标准(nginx不允许任何早于24小时的内容删除/过期cookie,发送无效的内容长度,因为错误消息已在内容计数之前进行了缓冲。 ..)。getallheaders函数调用通常可以在抽象代码情况下提供帮助,而php获取所有标头

示例包括:

<?php
//expire cookie
setcookie ( 'bookmark', '', strtotime('2012-01-01 00:00:00') );
// nginx will refuse this header response, too far past to accept
....
?>

还有这个:

<?php
header('Content-type: image/jpg');
?>

<?php   //a space was injected into the output above this line
header('Content-length: ' . filesize('image.jpg') );
echo file_get_contents('image.jpg');
// error! the response is now 1-byte longer than header!!
?>

1:验证或创建脚本日志,以确保您的线程到达正确的终点并且在完成之前没有退出。


3
这个答案打在了头上。有时,这不仅是nginx的配置,而且实际上是在生成标头。当error_reporting包含通知但php.ini中的display_errors关闭时,所有消息都显示在FCGI标头中而不是内容中。
Schien

17

Plesk说明

在Plesk 12中,我让nginx作为反向代理运行(我认为这是默认设置)。因此,当前的最佳答案不起作用,因为nginx也正在作为代理运行。

我去了Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings

然后,在该页面的底部,您可以设置其他nginx指令,我将其设置为此处的前两个答案的组合:

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
proxy_buffer_size   128k;
proxy_buffers   4 256k;
proxy_busy_buffers_size   256k;

1
哪里?哪个配置?
Redsandro

@Redsandro如果您找不到它,Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings那我不确定您的意思吗?
icc97

这是我的解决方案:域>域名> Apache和nginx设置>其他nginx指令Plesk Onyx版本17.8.11
dijkstra8x

1
我在一个新文件中添加了此文件,/etc/nginx/conf.d/proxy.conf然后重新启动了nginx,它工作正常,谢谢!
rubo77 '19


3

我们最终意识到,正在经历此操作的一台服务器已破坏了fpm config,从而导致通常会记录到磁盘的php错误/警告/通知正在通过FCGI套接字发送。当标头的一部分分散到缓冲区块中时,似乎存在解析错误。

因此,设置php_admin_value[error_log]为实际上可写的内容并重新启动php-fpm就足以解决问题。

我们可以使用较小的脚本重现该问题:

<?php
for ($i = 0; $i<$_GET['iterations']; $i++)
    error_log(str_pad("a", $_GET['size'], "a"));
echo "got here\n";

提高缓冲区使502s较难打,但并非不可能,例如,原生的:

bash-4.1# for it in {30..200..3}; do for size in {100..250..3}; do echo "size=$size iterations=$it $(curl -sv "http://localhost/debug.php?size=$size&iterations=$it" 2>&1 | egrep '^< HTTP')"; done; done | grep 502 | head
size=121 iterations=30 < HTTP/1.1 502 Bad Gateway
size=109 iterations=33 < HTTP/1.1 502 Bad Gateway
size=232 iterations=33 < HTTP/1.1 502 Bad Gateway
size=241 iterations=48 < HTTP/1.1 502 Bad Gateway
size=145 iterations=51 < HTTP/1.1 502 Bad Gateway
size=226 iterations=51 < HTTP/1.1 502 Bad Gateway
size=190 iterations=60 < HTTP/1.1 502 Bad Gateway
size=115 iterations=63 < HTTP/1.1 502 Bad Gateway
size=109 iterations=66 < HTTP/1.1 502 Bad Gateway
size=163 iterations=69 < HTTP/1.1 502 Bad Gateway
[... there would be more here, but I piped through head ...]

fastcgi_buffers 16 16k; fastcgi_buffer_size 32k;

bash-4.1# for it in {30..200..3}; do for size in {100..250..3}; do echo "size=$size iterations=$it $(curl -sv "http://localhost/debug.php?size=$size&iterations=$it" 2>&1 | egrep '^< HTTP')"; done; done | grep 502 | head
size=223 iterations=69 < HTTP/1.1 502 Bad Gateway
size=184 iterations=165 < HTTP/1.1 502 Bad Gateway
size=151 iterations=198 < HTTP/1.1 502 Bad Gateway

因此,我相信正确的答案是:修复您的fpm配置,使其将错误记录到磁盘。


1

搜索此错误时,这仍然是Google上最高的SO问题,因此让我们对其进行质疑。

当遇到此错误并且不想立即深入研究NGINX设置时,您可能需要检查到调试控制台的输出。以我为例,我正在将大量文本输出到FirePHP / Chromelogger控制台,由于所有这些都是作为标头发送的,因此导致了溢出。

如果此错误仅是由发送大量的日志消息引起的,则可能不需要更改Web服务器设置。


0

我不确定该问题与php发送的标头有关。确保已启用缓冲。简单的方法是创建一个proxy.conf文件:

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    100m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffering         on;
proxy_buffer_size       128k;
proxy_buffers           4 256k;
proxy_busy_buffers_size 256k;

还有一个fascgi.conf文件:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;
fastcgi_buffers 128 4096k;
fastcgi_buffer_size 4096k;
fastcgi_index  index.php;
fastcgi_param  REDIRECT_STATUS    200;

接下来,您需要通过以下方式在默认配置服务器中调用它们:

http {
  include    /etc/nginx/mime.types;
  include    /etc/nginx/proxy.conf;
  include    /etc/nginx/fastcgi.conf;
  index    index.html index.htm index.php;
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
    '"$request" $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
  #access_log   /logs/access.log  main;
  sendfile     on;
  tcp_nopush   on;
 # ........
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.