我正在设置一个LEMP堆栈来运行Drupal。我安装了Nginx和PHP-FastCGI。
Nginx工作正常,但任何运行PHP的尝试都给了我错误"502 Bad Gateway"。
谷歌快速透露:nginx 502网关坏了,增加缓冲区大小解决了这个问题。
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
问题是为什么?
我的理解
从上一个链接来看,nginx似乎正在向PHP-FastCGI发送请求,但它没有响应。这些请求使它超时怎么办?
它没有足够的时间做出响应,因为 php 很复杂(不是,它是phpinfo();
)。现在我已经增加了缓冲区,我什么时候应该担心必须再次增加缓冲区?
如果您检查nginx错误日志,很可能会看到以下消息:
upstream sent too big header while reading response header from upstream
fastcgi_buffers
设置用于 FastCGI 上游响应的缓冲区段的数量和内存大小。
文档中提供的默认值:fastcgi_buffers 8 4k|8k;
默认缓冲区大小等于操作系统的 PAGESIZE。
getconf PAGESIZE
允许获取当前内存页面大小。
例如,在 Ubuntu 14.01 中,默认的 PAGESIZE 为 4KB。这意味着,您有 8 个段,每个段 4KB。总计为 32KB。FastCGI的响应比这个数字多,这就是为什么我们得到响应代码502 - server received
这不是很好的解释,但我希望它能帮助你更好地理解。
,该问题仅与fastcgi_buffer_size
直接相关。这是一个非常特殊的缓冲区,仅保存响应中的 HTTP 标头。
如果您的应用程序发出大量 Set-Cookie
标头(或其他导致 HTTP 标头总大小的因素),则此处的默认缓冲区大小可能不够,您需要增加它。
要了解如何增加它,您可以在此处阅读我的超级详细文章 - 它是关于proxy_buffer_size
但fastcgi_
缓冲区的行为非常相似。引用基本命令:
curl -s -w %{size_header} -o /dev/null https://example.com
确保针对正确的 URL 进行测试,并在需要时通过 -H
添加请求标头。
这将为您提供以字节为单位的标头大小。然后,您需要将结果值与 4k(内存页的典型大小)对齐。
因此,如果您得到,例如 14342 字节,则需要设置:
fastcgi_buffer_size 16k;
棘手的部分不在那里,而是当你增加这个缓冲区大小时,由于NGINX使用/计算后者的默认值的方式,你也需要增加fastcgi_buffer_size
和/或fastcgi_busy_buffers_size
。
无论哪种方式,都不要将这些缓冲区设置得太高,并使用特定于应用的计算。 任意高的值不会对您的 RAM 有好处,因为这些缓冲区是每个连接使用的。
这个问题实际上可能与/var/lib/nginx/tmp
目录中容器中的权限有关(我们在 Alpine 上遇到了这种情况,但在其他发行版上也可能遇到这种情况)。该目录归nginx用户所有,只能由nginx组写入。当请求缓冲区超过缓冲区大小时/var/lib/nginx/tmp
将用作临时写入位置,直到释放足够的缓冲区来完成请求。写入tmp
目录的请求由无权写入该位置的www-user
(同样在 Alpine Linux 中)发出。
如果您在此处查看 Nginx 的预安装脚本(同样适用于 Alpine Linux),您会发现nginx
组正在添加到www-data
组中。这是安装所必需的,因为nginx用户负责安装和启动Nginx实例。之后,所有Nginx职责都移交给处理通过容器的http流量的www-data
用户。为了使www-data
用户能够写入/var/lib/nginx/tmp
目录,要么需要将目录的所有权更改为www-data
用户,要么需要将www-data
用户添加到nginx组中(这可能会带来安全问题)。
我在 Nginx 存储库上创建了一个问题,可以更好地解释这一点,并且如果您使用的是 Alpine Linux,还包含一个解决方法:https://gitlab.alpinelinux.org/alpine/aports/-/issues/12669
虽然这是一个 Alpine Linux 问题,但我怀疑其他对此有问题的人也遇到了类似的权限问题。解释其工作原理的Nginx文档可以在这里找到。
我知道这个问题很老了,但我们最近遇到了这个问题,花了大约一周的时间弄清楚,因为简单地增加缓冲区大小对我们来说似乎不是一个可行的长期解决方案。希望这可以使其他人免于一周的头痛,试图遇到相同的解决方案。