【问题标题】:Nginx 502 Bad Gateway. Solved by increasing buffer. Why?Nginx 502 错误网关。通过增加缓冲区来解决。为什么?
【发布时间】:2013-11-01 14:24:23
【问题描述】:

我正在设置一个 LEMP 堆栈来运行 Drupal。我安装了 Nginx 和 PHP-FastCGI。

Nginx 运行良好,但任何运行 PHP 的尝试都会给我错误“502 Bad Gateway”。

快速谷歌发现:nginx 502 bad gateway,增加缓冲区大小解决了这个问题。

fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;

问题是为什么?

我的理解

从上一个链接来看,似乎 nginx 正在向 PHP-FastCGI 发送请求,但它没有响应。这些请求导致超时怎么办?

它没有足够的时间来响应,因为 php 很复杂(不是,它是phpinfo();)。现在我已经增加了缓冲区,我什么时候应该担心必须再次增加缓冲区?

【问题讨论】:

  • 我只在某些 php 调用中获得了相同的 nginx 502 错误网关 - 并且添加缓冲区和缓冲区大小也对我有用。不知道为什么。
  • 这是一个很好的问题,虽然是在错误的论坛上。我也一直想知道这一点,这让我很恼火,每个解决方案都是如何在不说明原因的情况下增加缓冲区大小。多少是太多了?什么是太少了?为什么默认配置中没有这个?为什么YYYY?

标签: php nginx fastcgi


【解决方案1】:

如果您检查 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 响应的大小?
  • 这取决于您的应用程序,我猜; fpm 处理请求并呈现 nginx 接收的 html 输出。此输出的大小大于快速 cgi 缓冲区。
  • @antonbormotov 它缓冲整个响应,仅包含第一个块、响应标头?
  • @ThomasDecaux 据我了解,fastcgi_buffers 缓冲正文或其第一个块(如果响应大小较大),fastcgi_buffer_size 缓冲标题。
【解决方案2】:

其实问题只和fastcgi_buffer_size有直接关系。这是一个非常特殊的缓冲区,它只保存来自响应的 HTTP 标头。

如果您的应用程序发出大量 Set-Cookie 标头(或其他有助于 HTTP 标头总大小的因素),则此处的默认缓冲区大小可能不够,您需要增加它。

要了解如何你需要增加它,你可以阅读我的超级详细的文章here - 它是关于proxy_buffer_sizefastcgi_ 缓冲区的行为非常相似。引用基本命令:

curl -s -w \%{size_header} -o /dev/null https://example.com

如果需要,请确保针对正确的 URL 进行测试并通过 -H 添加请求标头。

这将为您提供以字节为单位的标头大小。然后,您需要将结果值与 4k(内存页的典型大小)对齐。

所以如果你有,例如14342字节,则需要设置:

fastcgi_buffer_size 16k;

棘手的部分不存在,而是事实上,当您增加此缓冲区大小时,您需要增加fastcgi_buffer_size 和/或fastcgi_busy_buffers_size 以及 NGINX 使用/计算后者的默认值。

无论哪种方式,都不要将这些缓冲区设置得太高,并使用特定于您的应用的计算。任意高的值对您的 RAM 没有好处,因为这些缓冲区是每个连接使用的。

【讨论】:

    【解决方案3】:

    这个问题实际上可能与/var/lib/nginx/tmp 目录中的容器权限有关(我们在 Alpine 上遇到过这种情况,但在其他发行版上也可能出现这种情况)。该目录归 nginx 用户所有,只能由 nginx 组写入。当请求缓冲区超过缓冲区大小时,/var/lib/nginx/tmp 将用作临时写入位置,直到有足够的缓冲区释放以完成请求。写入tmp 目录的请求是由无权写入该位置的www-user(同样在 Alpine Linux 中)发出的。

    如果您查看 Nginx 的预安装脚本 here(同样适用于 Alpine Linux),您会发现 nginx 组被添加到 www-data 组中。这是安装所必需的,因为 nginx 用户负责安装和引导 Nginx 实例。之后,所有 Nginx 职责都移交给 www-data 用户,该用户处理通过容器的 http 流量。为了使www-data 用户能够写入/var/lib/nginx/tmp 目录,目录的所有权需要更改为www-data 用户或www-data 用户需要添加到nginx 组(这可能会带来安全问题)。

    我在 Nginx 存储库上创建了一个问题,可以更好地解释这一点,并且如果您使用的是 Alpine Linux,还包含一个解决方法:https://gitlab.alpinelinux.org/alpine/aports/-/issues/12669

    虽然这是一个 Alpine Linux 问题,但我怀疑其他遇到此问题的人也遇到了类似的权限问题。可以在 here 找到解释其工作原理的 Nginx 文档。

    我知道这个问题很老了,但我们最近遇到了这个问题并花了大约一周的时间来解决这个问题,因为简单地增加缓冲区大小对我们来说似乎不是一个可行的长期解决方案。希望这可以让其他人免于为遇到相同的解决方案而头痛一周。

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2019-06-05
      • 2015-08-10
      • 2021-11-19
      • 2012-09-25
      • 2014-12-07
      • 2020-09-29
      • 2012-07-16
      • 2015-04-30
      相关资源
      最近更新 更多