【问题标题】:How to track down a Python/Django/uwsgi/nginx timeout如何追踪 Python/Django/uwsgi/nginx 超时
【发布时间】:2013-06-18 16:50:03
【问题描述】:

我有以下设置...

  • nginx 监听公共端口 80 并将请求代理到localhost:10000
  • 运行 django 站点 1 的 uwsgi 监听 localhost:10000 并生成一些网页。它还对localhost:10001 上的网络服务进行一些调用
  • 运行 django 站点 2 的 uwsgi 侦听 localhost:10001 以及其他内容,它在 otherhost:1234 上对 Web 服务进行一些调用

otherhost 忙碌时,一些请求预计最多需要 10 分钟才能完成。不幸的是,恰好 2 分钟后,nginx 给出了一个502 Bad Gateway

据我所知,问题必须是...

nginx 超时:

我认为这不太可能,因为那将是 504,但我正在使用:

proxy_read_timeout 1800;
proxy_connect_timeout 1800;

uwsgi #1 超时:

我正在像这样启动 uwsgi(在这两种情况下)

nohup uwsgi --http :8000 --chdir /opt/Path/To/Project --module Project.wsgi
            --virtualenv /opt/pyenv --enable-threads --logto /var/log/LogFile.log -p 1
            --threads 50 -t 1800 2> /dev/null &

Django 站点 1 调用站点 2:

调用如下:

    response = urllib.request.urlopen(Url, urlencode(Data).encode("utf-8"), 
               timeout=1800).read().decode("utf-8")

站点 2 调用其他站点:

这是由使用HTTPConnectionPool 的库完成的。我已经配置了 10 分钟的超时。我认为这不太可能,因为将其设置为(比如说)2s 会导致 Http 500 超时...

我已经扫描了我的代码库中的timeout(以及120120000,甚至在绝望中2),但我找不到设置超时的任何地方——我认为这是默认设置来自某事

如果我跳过 nginx 并这样做:

curl -m1800 -XGET 'http://localhost:10000/UI/Url'

我明白了

curl: (52) 来自服务器的空回复

正好一分钟后。

我有什么明显的遗漏吗?有什么好的方法可以追踪到这个?

【问题讨论】:

  • 任何超过几秒钟的网络服务都可能需要不同的解决方案。为什么不使用像 django-celery/redis 这样的任务队列?您的 djangosite2 会将任务添加到 otherhost:1234 将在空闲时接收并完成的队列。
  • 任务队列确实是处理此类事情的正确方法。 django-celery 确实是蜜蜂的膝盖,并且是您工具箱中非常有用的工具。我还发现自己在项目中增加了 uWSGI / nginx 超时,我可以在任何地方找到它们,并且在实施 django-celery 后我的生活变得更好。
  • 我们已经在左右和中间设置了 RabbitMQ 队列。事实上,长时间运行的调用会查询otherhost 的结果并将它们发布到队列中进行处理。我正在等待请求返回并告诉我有多少消息被泵入队列(大约 50-500k)

标签: python django nginx timeout uwsgi


【解决方案1】:

你有一个非常“奇怪”的设置:

nginx -> uwsgi http 路由器 -> uwsgi

而不是

nginx -> uwsgi

也许你有一些很好的理由,但在这种情况下,你需要设置超时时间 uwsgi http路由器和uwsgi via --http-timeout 1800

如果 http 路由器不是您想要/需要的,您可以让 uwsgi 使用 --http-socket 选项说 http

【讨论】:

  • 我可能不清楚。 2 个 uwsgi 进程在同一主机上运行,​​但用于逻辑上不同的目的。整个解决方案作为一个设备提供,集群中的所有机器都在私有虚拟网络上(如在每个集群中私有),除了绑定到公共 IP 地址(例如 LAN)的 nginx 端口 80。第一个 uwsgi 进程托管一个 django 站点,该站点使用 python 库来管理与第二个(Think UI 和 API)的连接
  • 我可能也不清楚:这与您的设置目的无关,您中间有一个 http 代理,默认情况下它的超时为 60 秒,您应该将其增加到相同的级别nginx。但是我仍然不确定您是否真的了解 --http 和 --http-socket 之间的区别
  • 显然不是。您能否编辑您的答案,明确您指的是哪个 uwsgi 实例并更详细地解释?虽然 uwsgi1 有时会调用 uwsgi2(有时不,有时每个请求多次)。我个人不会将其称为代理,因为处理和转换发生在中间。要么我们的术语不匹配,要么我们中的一个人遗漏了一些东西。谢谢:)
  • 当您使用 --http 而不是 --http-socket 时,会生成一个代理。 nginx 正在连接到它,并且此代理正在连接到托管应用程序的 uwsgi 实例。一切都是透明地发生的,但实际上您已经在设置中添加了另一层。
【解决方案2】:

尝试增加uwsgi_read_timeout

【讨论】:

    猜你喜欢
    • 2011-10-04
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 2014-05-31
    • 2015-12-25
    • 2018-08-17
    • 2013-09-21
    相关资源
    最近更新 更多