php 从上游读取响应标头时,上游发送了太大的标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23844761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
upstream sent too big header while reading response header from upstream
提问by Vidyut
I am getting these kind of errors:
我收到这些错误:
2014/05/24 11:49:06 [error] 8376#0: *54031 upstream sent too big header while reading response header from upstream, client: 107.21.193.210, server: aamjanata.com, request: "GET /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-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-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-brainwash-chronicles-sponsored-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsored-by-gujarat-government/,%20ht
2014/05/24 11:49:06 [错误] 8376#0:*54031 上游在从上游读取响应头时发送的头太大,客户端:107.21.193.210,服务器:aamjanata.com,请求:“GET /the-洗脑编年史-由古吉拉特邦政府赞助/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-由古吉拉特邦政府赞助/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by- gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsor-by-gujarat-government/ ,%20https:/aamjanata.com/the-brainwash-chronicles-sponsor-by-gujarat-government/,%20https:/aamjanata。com/the-brainwash-chronicles-sponsor-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-洗脑编年史-由古吉拉特邦政府赞助/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-由古吉拉特邦政府赞助/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by- gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https://aamjanata.com/the-brainwash-chronicles-sponsor-by-gujarat-government /,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsor-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsor-by-gujarat-government/,%20https:/aamjanata.com/the-洗脑编年史-由古吉拉特邦政府赞助/,%20https:/aamjanata.com/the-brainwash-chronicles-sponsed-by-gujarat-government/,%20https:/aamjanata.com/the-brainwash-chronicles-由古吉拉特邦政府赞助/,%20ht
Always it is the same. A url repeated over and over with comma separating. Can't figure out what is causing this. Anyone have an idea?
总是一样的。一个 url 用逗号分隔一遍又一遍地重复。无法弄清楚是什么原因造成的。有人有想法吗?
Update: Another error:
更新:另一个错误:
http request count is zero while sending response to client
Here is the config. There are other irrelevant things, but this part was added/edited
这是配置。还有其他不相关的东西,但这部分是添加/编辑的
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;
}
And then in the server block: set $skip_cache 0;
然后在服务器块中: set $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";
}`
回答by Neo
Add the following to your conf file
将以下内容添加到您的 conf 文件中
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
回答by amd
If nginx is running as a proxy / reverse proxy
如果 nginx 作为代理/反向代理运行
that is, for users of ngx_http_proxy_module
也就是说,对于用户 ngx_http_proxy_module
In addition to fastcgi
, the proxy
module also saves the request header in a temporary buffer.
除了fastcgi
,该proxy
模块还将请求头保存在临时缓冲区中。
So you may need also to increase the proxy_buffer_size
and the proxy_buffers
, or disable it totally (Please read the nginx documentation).
因此,您可能还需要增加proxy_buffer_size
和proxy_buffers
,或完全禁用它(请阅读nginx 文档)。
Example of proxy buffering configuration
代理缓冲配置示例
http {
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
Example of disabling your proxy buffer (recommended for long polling servers)
禁用代理缓冲区的示例(推荐用于长轮询服务器)
http {
proxy_buffering off;
}
For more information: Nginx proxy module documentation
更多信息:Nginx 代理模块文档
回答by ppostma1
upstream sent too big header while reading response header from upstream
is nginx's generic way of saying "I don't like what I'm seeing"
upstream sent too big header while reading response header from upstream
是 nginx 说“我不喜欢我所看到的”的通用方式
- Your upstream server thread crashed
- The upstream server sent an invalid header back
- The Notice/Warnings sent back from STDERR overflowed their buffer and both it and STDOUT were closed
- 你的上游服务器线程崩溃了
- 上游服务器发回了一个无效的标头
- 从 STDERR 发回的通知/警告溢出了它们的缓冲区,并且它和 STDOUT 都已关闭
3: Look at the error logs above the message, is it streaming with logged lines preceding the message? PHP message: PHP Notice: Undefined index:
Example snippet from a loop my log file:
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
you can see in the 3rd line from the bottom that the buffer limit was hit, broke, and the next thread wrote in over it. Nginx then closed the connection and returned 502 to the client.
您可以在从底部算起的第 3 行中看到缓冲区限制已达到、已中断,并且下一个线程将其写入。然后 Nginx 关闭连接并向客户端返回 502。
2: log all the headers sent per request, review them and make sure they conform to standards (nginx does not permit anything older than 24 hours to delete/expire a cookie, sending invalid content length because error messages were buffered before the content counted...). getallheaders function call can usually help out in abstracted code situations php get all headers
2:记录每个请求发送的所有标头,检查它们并确保它们符合标准(nginx 不允许超过 24 小时的任何东西删除/过期 cookie,发送无效的内容长度,因为错误消息在内容计数之前被缓冲。 ...)。getallheaders 函数调用通常可以在抽象代码情况下提供帮助php get all headers
examples include:
例子包括:
<?php
//expire cookie
setcookie ( 'bookmark', '', strtotime('2012-01-01 00:00:00') );
// nginx will refuse this header response, too far past to accept
....
?>
and this:
和这个:
<?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: verify, or make a script log, to ensure your thread is reaching the correct end point and not exiting before completion.
1:验证或制作脚本日志,以确保您的线程到达正确的终点并且在完成之前不退出。
回答by icc97
Plesk instructions
Plesk 说明
In Plesk 12, I had nginx running as a reverse proxy (which I think is the default). So the current top answer doesn't work as nginx is also being run as a proxy.
在 Plesk 12 中,我将 nginx 作为反向代理运行(我认为这是默认设置)。因此,当前的最佳答案不起作用,因为 nginx 也作为代理运行。
I went to Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings
.
我去了Subscriptions | [subscription domain] | Websites & Domains (tab) | [Virtual Host domain] | Web Server Settings
。
Then at the bottom of that page you can set the Additional nginx directiveswhich I set to be a combination of the top two answers here:
然后在该页面的底部,您可以设置其他 nginx 指令,我将其设置为此处前两个答案的组合:
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
回答by Lucas Bustamante
If you're using Symfony framework: Before messing with Nginx config, try to disable ChromePHP first.
如果您使用的是 Symfony 框架:在弄乱 Nginx 配置之前,请先尝试禁用 ChromePHP。
1 - Open app/config/config_dev.yml
1 - 打开 app/config/config_dev.yml
2 - Comment these lines:
2 - 注释这些行:
#chromephp:
#type: chromephp
#level: info
ChromePHP pack the debug info json-encoded in the X-ChromePhp-Data header, which is too big for the default config of nginx with fastcgi.
ChromePHP 将 json 编码的调试信息打包在 X-ChromePhp-Data 标头中,这对于带有 fastcgi 的 nginx 的默认配置来说太大了。
Source: https://github.com/symfony/symfony/issues/8413#issuecomment-20412848
来源:https: //github.com/symfony/symfony/issues/8413#issuecomment-20412848
回答by lyte
We ended up realising that our one server that was experiencing this had busted fpm config resulting in php errors/warnings/notices that'd normally be logged to disk were being sent over the FCGI socket. It looks like there's a parsing bug when part of the header gets split across the buffer chunks.
我们最终意识到我们遇到这种情况的一台服务器已经破坏了 fpm 配置,导致通常会记录到磁盘的 php 错误/警告/通知通过 FCGI 套接字发送。当部分标头跨缓冲区块拆分时,似乎存在解析错误。
So setting php_admin_value[error_log]
to something actually writeable and restarting php-fpm was enough to fix the problem.
因此,设置php_admin_value[error_log]
为实际可写的内容并重新启动 php-fpm 就足以解决问题。
We could reproduce the problem with a smaller script:
我们可以用更小的脚本重现这个问题:
<?php
for ($i = 0; $i<$_GET['iterations']; $i++)
error_log(str_pad("a", $_GET['size'], "a"));
echo "got here\n";
Raising the buffers made the 502s harder to hit but not impossible, e.g native:
提高缓冲区使 502 更难被击中,但并非不可能,例如原生:
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;
:
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
So I believe the correct answer is: fix your fpm config so it logs errors to disk.
所以我相信正确的答案是:修复您的 fpm 配置,以便将错误记录到磁盘。
回答by DavidKunz
This is still the highest SO-question on Google when searching for this error, so let's bump it.
在搜索此错误时,这仍然是 Google 上最高的 SO-question,所以让我们来看看它。
When getting this error and not wanting to deep-dive into the NGINX settings immediately, you might want to check your outputs to the debug console. In my case I was outputting loads of text to the FirePHP / Chromelogger console, and since this is all sent as a header, it was causing the overflow.
当收到此错误并且不想立即深入研究 NGINX 设置时,您可能需要检查调试控制台的输出。就我而言,我将大量文本输出到 FirePHP/Chromelogger 控制台,由于这些都是作为标头发送的,因此导致了溢出。
It might not be needed to change the webserver settings if this error is caused by just sending insane amounts of log messages.
如果此错误是由发送大量日志消息引起的,则可能不需要更改网络服务器设置。
回答by macherif
I am not sure that the issue is related to what header php is sending. Make sure that the buffering is enabled. The simple way is to create a proxy.conf file:
我不确定这个问题是否与 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;
And a fascgi.conf file:
还有一个 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;
Next you need to call them in your default config server this way:
接下来,您需要以这种方式在默认配置服务器中调用它们:
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;
# ........
}