Django Nginx-uwsgi(104:由对等方重置连接),同时从上游读取响应头

Django Nginx-uwsgi(104:由对等方重置连接),同时从上游读取响应头,django,nginx,uwsgi,Django,Nginx,Uwsgi,环境为Nginx+uwsgi 在某些GET请求上从Nginx获取502错误网关。似乎与URL的长度有关。在我们的例子中,这是一个很长的GET参数列表。缩短GET参数,无502错误 从nginx/error.log [error] 22113#0: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.1.100, server: s

环境为Nginx+uwsgi

在某些GET请求上从Nginx获取502错误网关。似乎与URL的长度有关。在我们的例子中,这是一个很长的GET参数列表。缩短GET参数,无502错误

从nginx/error.log

[error] 22113#0: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 192.168.1.100, server: server.domain.com, request: "GET <long_url_here>"
[error]22113#0:*1 recv()在从上游读取响应头时失败(104:由对等方重置连接),客户端:192.168.1.100,服务器:server.domain.com,请求:“GET”

uwsgi错误日志中没有任何信息。

在花了很多时间之后,我终于找到了答案。有许多关于Nginx和对等方重置连接的引用。其中大多数似乎与PHP有关。我找不到一个特定于Nginx和uwsgi的答案

我终于找到了一个对fastcgi的引用和一个502错误网关()。这导致我在uwsgi配置中寻找一个缓冲区大小限制,该限制存在为。默认值为4096。从文件中可以看出:

如果您计划接收包含大量头的大请求,可以将该值增加到64k(65535)

有很多方法可以配置uwsgi,我碰巧使用了一个.ini文件。因此,在我的.ini文件中,我尝试:

buffer-size=65535
这解决了问题。你可以根据口味来调整。也许从最大值开始,然后返回,直到得到一个可接受的值,或者只是将其保留在最大值


这是令人沮丧的追踪,因为uwsgi方面没有错误。

我得到了相同的nginx错误,而且uwsgi日志中也没有任何信息。问题在于,在某些情况下,应用程序没有按照以下建议使用整个请求主体:

如果HTTP请求有一个主体(如表单生成的POST请求),则必须在应用程序中读取(使用)它。如果不这样做,与Web服务器的通信套接字可能会被阻塞。如果您是懒惰的,您可以使用后缓冲选项,该选项将自动为您读取数据。对于机架应用,这是自动启用的


当然,这在您的情况下不是问题,但对于其他遇到相同nginx错误的人来说可能很有用。

我们只需要将php.ini中的属性“output_buffering”值增加到更大的值,如65535或其他适当的值。

您需要重新安装php:

apt-get install --reinstall php5-fpm

当我们在从上游读取响应头时收到类似于
(104:由对等方重置连接)的消息时,我们通常会将这种错误归咎于上游方

如上所述,连接由上游对等方重置,而不是由nginx本身重置。Nginx作为一个客户,几乎不能做任何事情来让它正确

我怀疑修改缓冲区大小是否会起作用。基本上,该命令更改缓存响应头的缓冲区大小。这将在响应头太大时生效,在这种情况下,当从上游读取响应头时,我们会收到一条消息说上游发送了太大的头,这与对等方重置连接完全不同

由于这种错误是随机触发的,我建议您检查nginx在与上游通话时是否使用
keepalive
。如果是这种情况,当空闲超时时,上游服务器可能会重置连接,而nginx不知道连接已断开,因此使用相同的连接转发请求

据我所知,没有优雅的解决方案来修复它。您可以在nginx中对上游连接池执行重试或设置
keepalive\u timeout
值,以避免出现问题

参考:

--后缓冲32768
按照这里的建议为我工作(并且感到沮丧)


我现在没有时间进一步研究它(快速原型模式:),但因为我花了很多时间找到这个黑客,所以可能值得在这里发布。

它不是偶尔出现的

我想最可能的原因是您的
phpfpm.log
太大了。尝试在
php fpm.conf
中将日志级别更改为更高级别,然后清除日志


不管怎样,它对我来说是有效的。

如果您的请求/响应头相当大,就会发生这种情况


为了解决这个问题,在/etc/uwsgi/apps available/your-app.ini中添加
buffer size=65535

您可能需要增加uwsgi中请求的最大大小:重新安装PHP应该如何解决这个问题?我相信这个答案与@eduan lenine的答案有关。不会影响任何事情。另外,
apt get install——仅升级php5 fpm
给我的信息是
php5 fpm已经是最新版本了。
。由于错误说明了从上游读取响应头的内容,那么它不应该是关于上游HTTP响应头字节大小的吗,不是HTTP请求头字节大小?它有很多头或者来自文档,还有大的查询字符串。在我的例子中,工作参数its
output_buffering=65535
在php.ini中,正如你提到的,很高兴服务!!!我使用gunicorn(Django)+nginx+docker,想要更改我的缓冲区大小值,怎么做?它真的有效,我输入了
/etc/uwsgi/sites/xxx.ini
,这个值,我已经重新启动了uwsgi服务,对于Django和python,感谢大家的贡献,这应该是对其他答案之一的评论?我已经找了很多天来解决这个问题,我一整天都在服务器上间歇性地看到这个问题,这为我解决了这个问题。在我的例子中,我将默认值4096加倍为8192。谢谢