Gunicorn: OSError: [Errno 11] Heroku 版本 19.8.1(和 19.8.0)上的资源暂时不可用

创建于 2018-05-29  ·  14评论  ·  资料来源: benoitc/gunicorn

我在 Heroku 上运行一个简单的 Flask 服务器:

web: gunicorn --worker-class eventlet -w 1 app:app --log-file=-

它使用 Python 2.7.15 与其他各种包兼容。

自从 Heroku 迁移到 v. 19.8.1 以来,我似乎从很久以前就遇到了这个问题的重复。 某些图像(大小从几 kb 到几 mb 不等)将无法加载; 我有一个包含大量图像(主要是动画精灵表)的站点,并且似乎每次都不会加载它们的随机选择,每次都会引发以下错误(如果图像是从早期版本缓存的,它会毫无问题地加载) :

2018-05-29T09:24:36.216949+00:00 app[web.1]: [2018-05-29 09:24:36 +0000] [10] [ERROR] Socket error processing request. 2018-05-29T09:24:36.216969+00:00 app[web.1]: Traceback (most recent call last): 2018-05-29T09:24:36.216971+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 66, in handle 2018-05-29T09:24:36.216972+00:00 app[web.1]: six.reraise(*sys.exc_info()) 2018-05-29T09:24:36.216974+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 56, in handle 2018-05-29T09:24:36.216976+00:00 app[web.1]: self.handle_request(listener_name, req, client, addr) 2018-05-29T09:24:36.216978+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 129, in handle_request 2018-05-29T09:24:36.216980+00:00 app[web.1]: six.reraise(*sys.exc_info()) 2018-05-29T09:24:36.216981+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/workers/async.py", line 112, in handle_request 2018-05-29T09:24:36.216983+00:00 app[web.1]: resp.write_file(respiter) 2018-05-29T09:24:36.216985+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/wsgi.py", line 403, in write_file 2018-05-29T09:24:36.216987+00:00 app[web.1]: if not self.sendfile(respiter): 2018-05-29T09:24:36.216989+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/wsgi.py", line 393, in sendfile 2018-05-29T09:24:36.216990+00:00 app[web.1]: sent += sendfile(sockno, fileno, offset + sent, count) 2018-05-29T09:24:36.216992+00:00 app[web.1]: File "/app/.heroku/python/lib/python2.7/site-packages/gunicorn/http/_sendfile.py", line 66, in sendfile 2018-05-29T09:24:36.216994+00:00 app[web.1]: raise OSError(e, os.strerror(e)) 2018-05-29T09:24:36.216996+00:00 app[web.1]: OSError: [Errno 11] Resource temporarily unavailable

这些是 requirements.txt 中的其他版本:

Flask==0.12.2 gunicorn==19.8.1 pymongo==3.6.1 flask_socketio==2.9.6 flask_cors==3.0.3 eventlet==0.22.1 gevent==1.2.2

将 gunicorn 更改为 19.7.1 似乎可以解决问题; 它在 19.8.0 中仍然存在。
与 2012 年的类似问题一样,这不是请求超时问题,因为它引发的错误非常直接。 回滚到 19.7.1 已修复它,所以现在我会坚持这样做,但使用最新版本会很好。 似乎这可能是 Heroku 特有的问题; 我只是在上个月左右才注意到,但找不到有关他们何时更改版本的任何信息。

最有用的评论

我今天整天都在为同样的问题而奋斗。 我_认为_我终于修好了。 我正在使用 nginx、Flask、gunicorn w/eventlet 和 docker。

我的(相关) pip freeze输出:

eventlet==0.23.0
Flask==1.0.2
greenlet==0.4.14
gunicorn==19.9.0

我的独角兽命令:
gunicorn -b 0.0.0.0:8000 --workers 1 --worker-class eventlet --log-level=DEBUG myapp.wsgi:app

第一个症状是大型静态文件加载在浏览器中抛出ERR_CONTENT_LENGTH_MISMATCH 。 显然,这破坏了应用程序,因为没有加载大型静态 JS 库。

第二个症状是 nginx 将以下内容记录到 error.log: upstream prematurely closed connection while reading upstream

最后,我将其追溯到一个 gunicorn 日志项:

Socket error processing request. - [in /usr/local/lib/python2.7/dist-packages/gunicorn/glogging.py:277]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 112, in handle_request
    resp.write_file(respiter)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 403, in write_file
    if not self.sendfile(respiter):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 393, in sendfile
    sent += sendfile(sockno, fileno, offset + sent, count)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/_sendfile.py", line 66, in sendfile
    raise OSError(e, os.strerror(e))
OSError: [Errno 11] Resource temporarily unavailable

我最终的解决方案是使用--no-sendfile标志启动 gunicorn,问题就消失了。 为什么? 不确定......我很高兴它正在工作。

另外值得一提的是,在我的故障排除过程中,我尽我所能让我的 nginx.conf 类似于此处找到的示例: http ://docs.gunicorn.org/en/stable/deploy.html

所有14条评论

我今天整天都在为同样的问题而奋斗。 我_认为_我终于修好了。 我正在使用 nginx、Flask、gunicorn w/eventlet 和 docker。

我的(相关) pip freeze输出:

eventlet==0.23.0
Flask==1.0.2
greenlet==0.4.14
gunicorn==19.9.0

我的独角兽命令:
gunicorn -b 0.0.0.0:8000 --workers 1 --worker-class eventlet --log-level=DEBUG myapp.wsgi:app

第一个症状是大型静态文件加载在浏览器中抛出ERR_CONTENT_LENGTH_MISMATCH 。 显然,这破坏了应用程序,因为没有加载大型静态 JS 库。

第二个症状是 nginx 将以下内容记录到 error.log: upstream prematurely closed connection while reading upstream

最后,我将其追溯到一个 gunicorn 日志项:

Socket error processing request. - [in /usr/local/lib/python2.7/dist-packages/gunicorn/glogging.py:277]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 66, in handle
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 129, in handle_request
    six.reraise(*sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/workers/base_async.py", line 112, in handle_request
    resp.write_file(respiter)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 403, in write_file
    if not self.sendfile(respiter):
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/wsgi.py", line 393, in sendfile
    sent += sendfile(sockno, fileno, offset + sent, count)
  File "/usr/local/lib/python2.7/dist-packages/gunicorn/http/_sendfile.py", line 66, in sendfile
    raise OSError(e, os.strerror(e))
OSError: [Errno 11] Resource temporarily unavailable

我最终的解决方案是使用--no-sendfile标志启动 gunicorn,问题就消失了。 为什么? 不确定......我很高兴它正在工作。

另外值得一提的是,在我的故障排除过程中,我尽我所能让我的 nginx.conf 类似于此处找到的示例: http ://docs.gunicorn.org/en/stable/deploy.html

我也遇到这个问题,19.7.0 工作正常

这是立即发生还是在部分发送长响应后发生?

可能是服务静态文件的原因

这事有进一步更新吗? 我在 19.9.0 中面临同样的问题

一切工作正常,突然之间它开始发生。

@tilgovi如果您需要有关此的一些信息,请告诉我。 突然这个问题开始出现

对我来说,问题是由于 eventlet 工作人员造成的。 我删除了 eventlet,现在一切都很好。

我遇到同样的问题。 @SaintSimmo的建议对我很有效。 开始下载大文件时会立即出现此问题。 我正在使用烧瓶和 eventlet。 下载工作是由 Flask 的 send_from_directory 完成的。
gunicorn 在以下命令中启动:
gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:4000上传:app
这将给出错误。
如果在命令中添加“--no-sendfile”,则不会发送错误消息。 如果可以在没有“sendfile”的情况下完成下载工作,那么什么时候应该使用这个“sendfile”呢?

gunicorn(版本 19.9.0)与 eventlet 相同的问题

在 19.9.0 上, @SaintSimmo设置--no-sendfile建议也对我有用。

是的,同样的问题,删除 eventlet 工作人员后它工作正常。

当我使用此命令(gunicorn -w 1 -k eventlet -b 127.0.0.1:5000 wsgi:app)启动服务器时,我收到以下异常,并且我的图像在客户端响应中被截断。
[ERROR] 套接字错误处理请求。
...
BlockingIOError: [Errno 11] 资源暂时不可用

删除工人阶级定义,它工作。
gunicorn -w 1 -b 127.0.0.1:5000 wsgi:app

@jacebrowning@SaintSimmo ,我确认 gunicorn 命令中的 --no-sendfile 额外参数是有效的。

这通常是由于nproc太少,您可以通过编辑文件“ /etc/security/limits.conf ”来增加运行该程序的用户的 nproc 数量。

你是否正在为这个问题而苦恼? 如果您使用的是 Python 3.4 或更高版本,请更新您的 Gunicorn 版本。

我对 --worker-class 有同样的问题。 我将 gunicorn 更新到 20.0.4,问题就解决了。

将工人阶级改为 gevent 对我有用。 --worker-class gevent

此页面是否有帮助?
0 / 5 - 0 等级