Gunicorn: 长时间运行请求后的即时工作超时

创建于 2013-08-08  ·  45评论  ·  资料来源: benoitc/gunicorn

我们遇到了一个非常奇怪的问题,涉及在 Heroku 上运行在我们的 Django 应用程序前面的 Gunicorn 的请求超时。

本质上,该问题发生在向应用程序发出非常长时间运行的请求时,导致它在 30 秒后被 Heroku 的平台级请求超时中断。 这本身不是问题 - 这种长时间运行的请求应该超时。 实际问题发生在后续请求中。 在这个长时间运行的请求之后发生的请求似乎有可能立即抛出以下形式的 Gunicorn 错误:

[CRITICAL] WORKER TIMEOUT (pid:15)

这会导致立即将内部服务器错误页面返回给客户端。 这种行为不一致——有时下一个请求会成功,有时不会。 我怀疑如果请求由处理长时间运行的请求的同一个 Gunicorn 工作人员处理,则会发生错误。

我们直接从 Django 运行 Gunicorn,如下所示:

python app/manage.py run_gunicorn -b 0.0.0.0:$PORT -w 2 -k gevent

其他相关的配置参数,例如 worker_connections 和 max_requests,设置为默认值。 但是,我们已经尝试更改这些设置以及工作人员的数量,但是在我们尝试过的所有情况下都会出现上述问题。 我们当前的 Gunicorn 版本是 0.14.6,在我们升级到 17.5 后回滚,以防这是问题的根源。 不幸的是,两个版本都会出现相同的行为。

我们很难理解这个问题的根本原因。 从上面链接的 Heroku 文档中:

当路由器向客户端返回响应时,您的应用程序将不知道它正在处理的请求已超时,您的应用程序将继续处理该请求。

我认为这意味着尽管从客户端的角度来看原始长时间运行的请求已超时,但 Gunicorn 工作人员仍在处理该请求。 令我感到困惑的是,鉴于工作人员正在使用 gevent 并因此使用异步线程来处理请求,这将如何导致新的后续请求立即引发工作人员超时。 我会认为第一个长期运行的请求是

  1. 由于有多个工作 gevent 线程,因此非阻塞,并且
  2. 在任何后续请求发生之前被 Gunicorn 杀死,因为 Gunicorn 的默认请求超时是 30 秒 - 与 Heroku 自己的请求超时相同。

值得一提的是,长时间运行的请求正在连接到我们的 PostgreSQL 数据库并执行几个复杂的查询。 崩溃似乎只发生在长时间运行的连接超时之后,这要归功于 Heroku 在与数据库交互时。 我们通过创建两个单独的视图在我们的测试服务器上对此进行了测试,其中一个对数据库执行长查询,直到达到 Heroku 超时,而另一个只是等待超过 30 秒标记以生成 Heroku 超时。 前一个视图能够在下一个请求中导致 Gunicorn 工作器超时,而“睡眠”视图则不是。

如果有人对导致此问题的潜在行为有任何了解,那就太好了 - 我可以提供任何其他信息来帮助诊断问题,请告诉我。 我希望这是处理此类问题的正确方法,并且之前没有提出/解决过。

( FeaturWorker - Bugs -

所有45条评论

@Jwpe优秀的错误报告。

我要调查的第一件事是您是否使用绿色的 PostgreSQL 驱动程序。 曾经有一个特定版本,您需要将其与猴子补丁一起使用才能使其正常工作。 我不知道现在的情况。 但是您粘贴的超时是工作超时,并且在其中一个异步工作中基本上归结为“greenlet 没有超过 $timeout 秒”。 鉴于您正在描述长时间运行的 PostgreSQL 请求,这是我首先要调查的地方。

@davisp感谢您对此的快速反应!

按照您的指示,我查看了 psycopg2 适配器——我们用它来将我们的 Django 应用程序连接到 Postgres——并发现了文档的这一部分,其中指出:

警告:Psycopg 连接不是绿色线程安全的,不能被不同的绿色线程同时使用。 尝试使用每个线程一个游标一次执行多个命令将导致错误(或 2.4.2 之前的版本死锁)。
因此,建议程序员要么避免在协程之间共享连接,要么使用库友好的锁来同步共享连接,例如用于池化。

换句话说 - psycopg2 不喜欢绿色线程。 根据我们遇到的行为,我猜这就是错误的根源。 根据 psycopg 文档,处理此问题的建议方法是使用一个库,该库为协程启用 psycopg 支持。 推荐的库是psycogreen

我将尝试使用 psycogreen 库在我们的测试服务器上重新创建问题,看看它是否能解决问题。 希望我应该能够相对较快地报告一些结果。

@Jwpe这看起来像我记得的钩子。

@benoitc也许我们应该在 Gunicorn 文档中的某个地方指出这一点? 不完全确定最好的地方在哪里。

@davisp可能在常见问题解答部分?

hmppff 忘记它已经存在 (http://docs.gunicorn.org/en/latest/faq.html) 所以也许我们可以从那里获得“故障排除”部分的链接。 不确定,但我们也可以在此部分中移动有关 virtualenv 和其他技巧的任何信息。

也许是一个警告或“关于绿线的注意事项”页面。 不是超级紧迫。

我在 Heroku 上看到了几乎完全相同的行为,使用 gevent 工作人员和其他一些工作人员运行 gunicorn,所以我切换到同步工作人员,如该线程所推荐的那样,并且仍然看到基本相同的严重问题。 我会得到一个 H12 30 秒的 Heroku 截止时间,然后重复 H12 和[CRITICAL] Worker Timeout错误,直到我重置整个 dyno(有时一个小时或更长时间后,或者直到达到最大请求)。 所以我将 gunicorn 超时调整为 28 秒,以便在 Heroku 切断它之前超时。 相同(或非常相似)的问题每天发生一两次并持续到主进程重新启动,只是这次它以 H13(连接关闭)开始,因为 gunicorn 将其切断。 在此期间,流量没有显着高峰。

这是我当前的 procfile 条目:

web: newrelic-admin run-program gunicorn publisher.wsgi -b 0.0.0.0:$PORT -w 4 --max-requests 1000 --timeout 28 --preload

系列活动详情:

首先,我收到一些似乎需要很长时间(5 秒以上)的请求,然后请求因 H12 超时而失败(工作器超时将其切断),并且还有一些请求将完成,但时间非常长(20秒)。 从那时起,它是纯 H11 30 秒 heroku 截止时间,直到我重新启动 dyno。

我们使用 gunicorn (v 18.0) 作为我们的网络服务器(运行 python/django)。

我们运行 newrelic,它显示了停机时间和疯狂增加的请求排队时间,但没有提供其他见解。 我在 NR 中没有看到吞吐量峰值或其他异常情况。 我们使用 papertrail 进行日志处理并发送错误电子邮件。

Oct 15 15:08:53 nutrislice-stockton heroku/router: at=info method=GET path=/marketingtools/api/slides/?format=json-p&callback=_jqjsp&_1381871332239= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=15ms service=216ms status=200 bytes=21 Oct 15 15:08:54 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/menutypes/?format=json-p&callback=_jqjsp&_1381871332232= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=2ms service=90ms status=200 bytes=231 Oct 15 15:08:56 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871323514= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=3ms service=94ms status=200 bytes=5986 Oct 15 15:09:03 nutrislice-stockton heroku/router: at=info method=HEAD path=/heartbeat/ host=stockton.nutrislice.com fwd="54.247.188.179" dyno=web.2 connect=3ms service=23ms status=200 bytes=0 Oct 15 15:09:13 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871237946= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=5ms service=166ms status=200 bytes=468 Oct 15 15:09:20 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871323611= host=oldham.nutrislice.com fwd="74.138.24.95" dyno=web.2 connect=6ms service=183ms status=200 bytes=453 Oct 15 15:09:40 nutrislice-stockton heroku/router: at=info method=GET path=/ host=nps.nutrislice.com fwd="74.190.240.28" dyno=web.2 connect=1ms service=260ms status=200 bytes=35951 Oct 15 15:09:55 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/api/list/school-menu-profile/87/menu-type/43/?format=json-p&callback=jQuery18008709754704032093_1381871379465&_=1381871393589 host=nps.nutrislice.com fwd="74.190.240.28" dyno=web.2 connect=15ms service=129ms status=200 bytes=400 Oct 15 15:09:55 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/api/list/school-menu-profile/306/menu-type/187/?format=json-p&callback=jQuery180013075259909965098_1381873891397&_=1381873896600 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=2ms service=33ms status=200 bytes=486 Oct 15 15:10:00 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/186/?smp=257 host=coppellisd.nutrislice.com fwd="76.199.114.157" dyno=web.2 connect=7ms service=103ms status=200 bytes=323 Oct 15 15:10:00 nutrislice-stockton app/web.2: INFO http://stockton.nutrislice.com/heartbeat/ Pinged from IP: 10.190.159.205 -- AGENT: NewRelicPinger/1.0 (269661) Oct 15 15:10:00 nutrislice-stockton heroku/router: at=info method=HEAD path=/heartbeat/ host=stockton.nutrislice.com fwd="50.112.95.211" dyno=web.2 connect=1ms service=10ms status=200 bytes=0 Oct 15 15:10:09 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/239/?smp=341 host=edenpr.nutrislice.com fwd="75.73.177.139" dyno=web.2 connect=8ms service=334ms status=200 bytes=277 Oct 15 15:10:16 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/395/?smp=306 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=1ms service=96ms status=200 bytes=245 Oct 15 15:10:20 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/391/?smp=305 host=sdhc.nutrislice.com fwd="173.170.34.126" dyno=web.2 connect=32ms service=5207ms status=200 bytes=290 Oct 15 15:10:22 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/350/?smp=305 host=sdhc.nutrislice.com fwd="173.170.34.126" dyno=web.2 connect=60ms service=7676ms status=200 bytes=1147 Oct 15 15:10:31 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/258/?smp=341 host=edenpr.nutrislice.com fwd="75.73.177.139" dyno=web.2 connect=42ms service=517ms status=200 bytes=26974 Oct 15 15:10:43 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871432885= host=ocps.nutrislice.com fwd="71.47.21.97" dyno=web.2 connect=1490ms service=9883ms status=200 bytes=1565 Oct 15 15:10:52 nutrislice-stockton heroku/router: at=error code=H13 desc="Connection closed without response" method=GET path=/ host=jordandistrict.nutrislice.com fwd="71.199.48.37" dyno=web.2 connect=1959ms service=29230ms status=503 bytes=0 Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [2] [CRITICAL] WORKER TIMEOUT (pid:12) Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [2] [CRITICAL] WORKER TIMEOUT (pid:12) Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50 [26] [INFO] Booting worker with pid: 26 Oct 15 15:10:52 nutrislice-stockton app/web.2: 2013-10-15 21:10:50,930 (26/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:10:54 nutrislice-stockton heroku/router: at=info method=GET path=/surveys/api/activesurveycount/?format=json-p&callback=_jqjsp&_1381871433429= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1181ms service=20074ms status=200 bytes=32 Oct 15 15:10:55 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871433374= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1136ms service=20393ms status=200 bytes=142 Oct 15 15:11:01 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:01 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:01 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:01 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871432922= host=ocps.nutrislice.com fwd="71.47.21.97" dyno=web.2 connect=1435ms service=23198ms status=200 bytes=486 Oct 15 15:11:03 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/conf/urls/defaults.py:3: DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead Oct 15 15:11:03 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:05 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871443300= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1089ms service=20040ms status=200 bytes=268 Oct 15 15:11:10 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/weeks/school-menu-profile/135/menu-type/63/2013/10/14/?format=json-p&callback=_jqjsp&_1381871439548= host=henrico.nutrislice.com fwd="96.248.5.53" dyno=web.2 connect=1018ms service=30001ms status=503 bytes=0 Oct 15 15:11:15 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/sales/?format=json-p&callback=_jqjsp&_1381871443267= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1096ms service=30001ms status=503 bytes=0 Oct 15 15:11:15 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871443296= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1108ms service=30000ms status=503 bytes=0 Oct 15 15:11:23 nutrislice-stockton heroku/router: at=info method=GET path=/menu/api/weeks/school-menu-profile/48/menu-type/21/2013/10/14/?format=json-p&callback=_jqjsp&_1381871449451= host=martinschools.nutrislice.com fwd="99.114.229.202" dyno=web.2 connect=1114ms service=31756ms status=200 bytes=48771 Oct 15 15:11:26 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/sales/?format=json-p&callback=_jqjsp&_1381871455129= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=990ms service=30001ms status=503 bytes=0 Oct 15 15:11:26 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871455291= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=1028ms service=30008ms status=503 bytes=0 Oct 15 15:11:31 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/179/?smp=6 host=cusdnutrition.nutrislice.com fwd="68.99.246.16" dyno=web.2 connect=2492ms service=30000ms status=503 bytes=0 Oct 15 15:11:32 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/192/?smp=6 host=cusdnutrition.nutrislice.com fwd="68.99.246.16" dyno=web.2 connect=2713ms service=30003ms status=503 bytes=0 Oct 15 15:11:39 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/ host=hebisd.nutrislice.com fwd="38.107.226.1" dyno=web.2 connect=2115ms service=30001ms status=503 bytes=0 Oct 15 15:11:45 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/weeks/school-menu-profile/44/menu-type/19/2013/10/14/?format=json-p&callback=_jqjsp&_1381871472583= host=pcsb.nutrislice.com fwd="66.87.110.127" dyno=web.2 connect=2168ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/marketingtools/api/active-announcements/?format=json-p&callback=_jqjsp&_1381871476287= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=1927ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/surveys/api/activesurveycount/?format=json-p&callback=_jqjsp&_1381871476543= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=2117ms service=30000ms status=503 bytes=0 Oct 15 15:11:48 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schooltypes/?format=json-p&callback=_jqjsp&_1381871476481= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=2111ms service=30009ms status=503 bytes=0 Oct 15 15:11:50 nutrislice-stockton app/web.2: 2013-10-15 15:11:32,597 (26/NR-Activate-Session/nutrislice-stockton) newrelic.core.data_collector INFO - Successfully registered New Relic Python agent where app_name='nutrislice-stockton', pid=26, redirect_host='collector-2.newrelic.com' and agent_run_id=474482914, in 40.26 seconds. Oct 15 15:11:50 nutrislice-stockton app/web.2: INFO Successfully registered New Relic Python agent where app_name='nutrislice-stockton', pid=26, redirect_host='collector-2.newrelic.com' and agent_run_id=474482914, in 40.26 seconds. Oct 15 15:11:52 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/marketingtools/api/active-announcements/?format=json-p&callback=_jqjsp&_1381871480294= host=sdhc.nutrislice.com fwd="65.34.72.116" dyno=web.2 connect=1689ms service=30006ms status=503 bytes=0 Oct 15 15:11:55 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871482566= host=henrico.nutrislice.com fwd="72.84.233.45" dyno=web.2 connect=2067ms service=30004ms status=503 bytes=0 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [2] [CRITICAL] WORKER TIMEOUT (pid:26) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [2] [CRITICAL] WORKER TIMEOUT (pid:26) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41 [29] [INFO] Booting worker with pid: 29 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:41,067 (29/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [2] [CRITICAL] WORKER TIMEOUT (pid:23) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [2] [CRITICAL] WORKER TIMEOUT (pid:23) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44 [32] [INFO] Booting worker with pid: 32 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:44,154 (32/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [2] [CRITICAL] WORKER TIMEOUT (pid:14) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [2] [CRITICAL] WORKER TIMEOUT (pid:14) Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48 [35] [INFO] Booting worker with pid: 35 Oct 15 15:11:57 nutrislice-stockton app/web.2: 2013-10-15 21:11:48,273 (35/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:11:57 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:11:57 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:11:57 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:11:57 nutrislice-stockton heroku/router: at=info method=GET path=/menuwidgets/353/?smp=306 host=sdhc.nutrislice.com fwd="72.186.96.121" dyno=web.2 connect=21ms service=76ms status=200 bytes=255 Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [2] [CRITICAL] WORKER TIMEOUT (pid:13) Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [2] [CRITICAL] WORKER TIMEOUT (pid:13) Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54 [38] [INFO] Booting worker with pid: 38 Oct 15 15:12:00 nutrislice-stockton app/web.2: 2013-10-15 21:11:54,388 (38/MainThread) newrelic.core.agent INFO - New Relic Python Agent (2.0.0.1) Oct 15 15:12:00 nutrislice-stockton app/web.2: using heroku production settings Oct 15 15:12:01 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/utils/hashcompat.py:9: DeprecationWarning: django.utils.hashcompat is deprecated; use hashlib instead Oct 15 15:12:01 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:12:02 nutrislice-stockton app/web.2: WARNING /app/.heroku/python/lib/python2.7/site-packages/django/conf/urls/defaults.py:3: DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead Oct 15 15:12:02 nutrislice-stockton app/web.2: DeprecationWarning) Oct 15 15:12:03 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/353/?smp=306 host=sdhc.nutrislice.com fwd="108.9.154.78" dyno=web.2 connect=3650ms service=30006ms status=503 bytes=0 Oct 15 15:12:03 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menuwidgets/395/?smp=306 host=sdhc.nutrislice.com fwd="108.9.154.78" dyno=web.2 connect=3581ms service=30006ms status=503 bytes=0 Oct 15 15:12:06 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/settings/?format=json-p&callback=_jqjsp&_1381871492466= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3582ms service=30001ms status=503 bytes=0 Oct 15 15:12:09 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/mobile/api_version/?deviceType=iphone host=pasco.nutrislice.com fwd="173.65.148.9" dyno=web.2 connect=3837ms service=30004ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/mobile/api_version/?deviceType=iphone host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3987ms service=30001ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/schools/?format=json-p&callback=_jqjsp&_1381871497105= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=3962ms service=30001ms status=503 bytes=0 Oct 15 15:12:11 nutrislice-stockton heroku/router: at=error code=H12 desc="Request timeout" method=GET path=/menu/api/menutypes/?format=json-p&callback=_jqjsp&_1381871497128= host=canyonsdistrict.nutrislice.com fwd="174.52.155.49" dyno=web.2 connect=4020ms service=30007ms status=503 bytes=0
并且这种 H12 超时和 [CRITICAL] WORKER TIMEOUT 的“死亡螺旋”持续不断,直到主进程重新启动。

如果这是相同的问题还是不同的问题,有什么想法吗? 有什么建议可以解决吗? 我认为,由于 gunicorn 在超时后杀死工作进程并重新启动它们,因此它们能够正常开始处理事情,但之后似乎请求甚至没有到达它们。 也许是 Heroku 的问题。

:+1: 也看到了这个问题。

我也在 Heroku 上看到了这个问题

@sprynmr @richardkeen你能分享你启动 gunicorn 的方式和任何日志吗? 解决这个问题会有很大帮助。

@nebstrebor如果您不限制请求数量怎么办?

我们是这样启动的:
web: newrelic-admin run-program python manage.py run_gunicorn -b "0.0.0.0:$PORT" --log-level=DEBUG -w 3 -k gevent --max-requests 250

即使使用日志级别的调试,我们也没有太多关于正在发生的事情的日志。 暂时不使用gevent已经为我们解决了问题,但并不理想。

@sprynmr如果删除最大请求数会怎样? 还有哪个版本的gevent?

我们在1.0rc2 。 不确定最大请求数。 现在不想为我们的生产环境重新打开它。

阅读有关请求超时的 Heroku 页面,他们建议设置应用程序超时well under 30 seconds, such as 10 or 15 。 您是否尝试过使用 gunicorn 中的超时参数的建议?

无论如何,gevent 出现的问题可能是由于处理连接的方式造成的。 当前版本的 worker 正在生成一个 greenlet / 接受的连接,而没有对这个 greenlet 进行任何真正的监督。 可能发生的情况是,其中一个被接受的套接字将等待很长时间,并且没有处理其他事件,从而使 gunicorn 工作器重新启动。 但我需要检查..

有趣的。 不,我们没有尝试过。

:+1: 我也在我的申请中看到了这一点。 @Jwpe / @sprynmr你有没有解决过这个问题? 似乎已经超过 2 个月没有针对此问题进行任何活动了。 我很想知道您是否找到了解决问题的方法。

谢谢!

@dencold你有没有试过https://github.com/benoitc/gunicorn/issues/588#issuecomment -29267541

我在 heroku 上没有帐户,所以不确定它的作用。 你也有相同的日志吗?

@benoitc ,非常感谢您的快速回复。 日志与@Jwpe@nebstrebor报告的完全相同。 如果这有助于隔离问题,我很高兴提取相关部分并将它们添加到此处,请告诉我。

我将从您之前的评论中获取您的建议,并将 gunicorn 超时配置为低于 heroku 路由器超时,看看是否有帮助。 谢谢你的建议。

找出这种级联故障的实际原因会很有帮助。 看到一个工人失败,然后整个 gunicorn 服务器变得完全没有响应,这真的很奇怪。 如果我能做些什么来帮助诊断,请告诉我。 我无法在本地重现此超时。 它似乎只发生在 heroku 基础设施上。

抱歉@dencold我从来没有找到解决方案。 似乎是个很深奥的神秘虫子,我没时间和它战斗。 很想知道超时位是否对您有帮助。 回来汇报。

@dencold你也在使用新遗物吗?

@benoitc是的,我们也在使用新遗物。

@dencold同样,我们从未成功解决此问题。 我们没有时间花时间找出导致错误的原因,需要专注于减少原始请求的持续时间。 然而,错误的关键性质——因为它是面向用户的——导致我们切换 WSGI 服务器以避免在此期间出现问题。 因此,我们还没有进行任何进一步的实验来进一步对问题进行分类。

@Jwpe您至少尝试过建议的解决方案吗? 结果也很奇怪,我从不单独用 gunicorn 重现它。

我将截止时间缩短到 15 秒,但问题仍然存在

2014 年 1 月 26 日,星期日,Benoit Chesneau通知@ github.com
写道:

@Jwpe https://github.com/Jwpe您是否至少尝试过建议的
解决方案? 结果也很奇怪,我从来没有用 gunicorn 重现它
通过它自己。


直接回复本邮件或在Gi tHub上查看
.

本·罗伯茨
首席技术官
Nutrislice, Inc.
866-524-3444 转 702
[email protected]

@Jwpe / @nebstrebor非常感谢您重新讨论这个问题。

@benoitc我们已经在我们的 heroku 实例上实现了提议的超时解决方案。 在接下来的几天里,我将密切关注此事。 如果我在新的超时到位后看到同样的问题弹出,我会回帖。

再次感谢大家的帮助。 很高兴知道我不是唯一遇到此问题的人。 希望我们能追根溯源。

@benoitc只是想报告一下,已经有大约两周的时间了,超时时间较短。 我们已经看到了几个工人超时,但没有一个会导致整个 gunicorn 进程变得无响应。 这似乎解决了问题,但我仍然不确定为什么 30 秒超时首先会导致级联错误。

只是想让你知道。 再次感谢这里的所有帮助!

在 Raspberry PI 中使用 gunicorn 运行 Django 时出现相同的 [CRITICAL] WORKER TIMEOUT 错误。

没消息。

我得到了相同的 [CRITICAL] 工人超时。
问题是在工作人员的真正超时(长请求)之后,gunicorn 会杀死工作人员并尝试生成新工作人员,但新工作人员无法在 TIMEOUT 限制内启动,并且无法到达它通知父进程的位置活,所以枪炮一次又一次地杀死它:(。在我们的例子中,问题与 Gevent 和 Sentry(https://github.com/getsentry/raven-python/issues/305)有关。Sentry 只是挂在启动时.
顺便说一句,为工作程序启动时间设置单独的超时以及工作程序中无法在“超时”时间内启动的一些附加日志会很有帮助。

除了同步工作者之外,超时不是请求超时。 即使在处理长请求时,其他工作人员仍然会向仲裁者发出心跳。 超时时间就是这种情况下的启动超时时间。

从某种意义上说,gunicorn 中没有“请求超时”。

是的,工作超时与异步中的请求超时不同。 但是没有任何函数调用的长时间运行的请求可能发生异步“上下文切换”(如“套接字 - 读/写”)是工作超时的原因。 此外,工作启动时可能会超时(根本没有请求)。 但是在 Gunicorn 日志中,无法区分这两种不同的情况,只有一条消息“工人超时”。

我们应该添加请求超时设置吗? 这将使启动时间较长的应用程序增加工作超时。

不要这样认为,因为
1)测量请求的运行时间很难,我们不能在请求和请求结束时使用时间差。
2)据我所知,在gevent中不可能捕获“执行单元”(在上下文切换之间运行的代码量)的超时。

那有什么建议吗?

如果此问题仅是由于合法超时和潜在的级联
由于首次运行时不存在的服务器负载而导致的超时,是否存在
在这里有什么可做的? 或者这个问题是否可以关闭,这个问题处理得更好
在不同级别的基础设施上运行?
2014 年 7 月 30 日下午 1:14,“Mkrtich”通知@github.com 写道:

不要这样认为,因为
1) 测量请求运行时间很难,我们不能使用时间差
乞求并在请求结束时。
2)据我所知,捕获“执行单元”的超时(代码量
在上下文切换之间运行)在 gevent 中是不可能的。


直接回复此邮件或在 GitHub 上查看
https://github.com/benoitc/gunicorn/issues/588#issuecomment -50673040。

建议是有 2 个超时参数和 2 个不同的日志。
1) 一个是当前超时参数,仅在请求处理期间有效。
2)第二个将是工人启动超时。

也看到这个问题

我们最终为 Heroku 切换到 uWSGI 并且取得了更好的成功......我意识到这不是 Gunicorn 的修复程序,但我认为该建议可能对在生产服务器上看到此问题并需要尽快解决的人有所帮助.

@nebstrebor好吧,您是否尝试过降低超时的建议?

@CrazyPython票已关闭。 您能否开一张新票来描述您遇到的问题以及我们如何重现它? 确定它是否是同一问题,其他问题和合作肯定会有所帮助:)

是的,它没有任何区别,如上所述。 问题是零星的
足够(永远无法繁殖)和灾难性的,我们不得不
采取行动(已经一年多了)。 不过我真的很喜欢Gunicorn,
我们在 Heroku 之外使用它没有问题。

本·罗伯茨
首席技术官兼联合创始人
Nutrislice, Inc.
[email protected]
手机 - 801-735-7845

2015 年 6 月 30 日,星期二,上午 8:08,Benoit Chesneau通知@ github.com
写道:

@nebstrebor https://github.com/nebstrebor你试过了
建议降低超时?

@CrazyPython https://github.com/CrazyPython 票已关闭。
你能开一张新票吗描述你遇到的问题以及我们如何做
重现它? 确定是否是同一个问题肯定会有所帮助,
别的东西和合作:)


直接回复此邮件或在 GitHub 上查看
https://github.com/benoitc/gunicorn/issues/588#issuecomment -117199606。

我想我们也看到了这个问题。 两个工作人员(--workers 2)都挂断了一些长时间运行的请求,最终被杀死(--timeout 20),我们立即看到两个 H13,然后我们开始得到 H12s & WORKER TIMEOUT 重新启动。 在接下来的 10 分钟内,这种情况仍在继续,工作人员在超时并重新启动之前从未成功处理过请求。 所以,我们重新启动了测功机,并修复了它。

我注意到一件有趣的事情,我没有看到其他人注意到 - 我们在问题开始时看到两个 H13(连接关闭而没有响应),然后当我们最终发出 SIGTERM 时,我们看到了大量的 H13 - 48准确地说,这与我们看到的 WORKER TIMEOUT 的数量相同(不包括我们看到的 H13 立即发生的前两个)。 我不太确定这意味着什么,但似乎很可疑......

什么是 H13s 或 H12s? 这是来自heroku的东西吗? 如何给出 gunicorn 将绑定的端口? 我怀疑 heroku 代理没有检测到套接字已关闭。

还有你使用的是哪个工人?

是的,它们是 Heroku 错误代码:
H12 - 请求超时 - 通常为 30 秒(https://devcenter.heroku.com/articles/error-codes#h12-request-timeout)
H13 - 连接关闭无响应 - (https://devcenter.heroku.com/articles/error-codes#h13-connection-closed-without-response)

编辑:我刚刚注意到,如果 PORT 作为环境变量存在,gunicorn 将使用它,所以这就是端口的配置方式。

我们正在使用同步工作者。

而且我也忘了提及,我们正在运行 gunicorn 19.3.0

关闭问题,因为很长一段时间以来没有发生任何活动。 也许延迟超时对长时间启动的应用程序有好处,但如果需要,应该在另一张票中完成。

嘿,我也面临与 heroku 上的 gunicorn uvicorn 相同的问题,使用 new-relic admin procfile:

newrelic-admin run-program gunicorn -w 4 -k uvicorn.workers.UvicornWorker app.main:fastapi_app -b 0.0.0.0:${PORT:-5000} --log-level info --access-logfile=- --logger-class=gunicorn_color.Logger --preload

这会在系统启动后立即引导我查看此日志:

2021-03-19T13:18:19.187532+00:00 heroku[web.1]: State changed from starting to up
2021-03-19T13:18:51.964740+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/" host=api-app-clienti-pr-49.herokuapp.com request_id=8742009a-3e56-4f83-a147-97ff84d4e30b fwd="5.89.111.249" dyno=web.1 connect=1ms service=30003ms status=503 bytes=0 protocol=https
2021-03-19T13:19:04.292784+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/api" host=api-app-clienti-pr-49.herokuapp.com request_id=85b6320a-7728-4074-87eb-b0992e7c3f9d fwd="5.89.111.249" dyno=web.1 connect=3ms service=30001ms status=503 bytes=0 protocol=https
此页面是否有帮助?
0 / 5 - 0 等级