【问题标题】:Gunicorn Django ThreadingGunicorn Django 线程
【发布时间】:2014-07-23 04:38:36
【问题描述】:

我无法找到有关 Gunicorn/Django 进程/线程生命周期的文档。

假设在 process_response() 中间件挂钩期间产生了一个守护线程。 AFAIK 这个线程不会阻止 HTTP 响应。但是,它会阻塞产生它的线程吗?在工作进程准备好处理另一个请求之前,Gunicorn 是等待该线程完成后再将其加入主线程,还是会分离该线程?

data_collection/tasks.py:

from celery import shared_task

@shared_task(ignore_result=True)
def add_event(event_name, event_body):
    ...
    client.add_event(event_name, event_body)

data_collection/middleware.py:

import threading
from data_collection.tasks import add_event

class DataCollectionMiddleware:
    def process_response(self, request, response):
        ...
        thread = threading.Thread(target=add_event.delay, args=("Page_Views", event_body))
        thread.setDaemon(True)
        thread.start()

更多细节:

我编写了一个自定义中间件类来将一些数据发送到外部队列 (RabbitMQ),稍后由 celery worker 异步检索和处理。我不希望这个在线入队调用阻塞客户端的响应,所以我将该函数 (add_event.delay()) 包装在一个“守护进程”线程中 (a la http://www.artfulcode.net/articles/threading-django/)。如果网络中断并且重试策略有很长的限制,则此线程可能会运行很长时间。在那种情况下,这些线程会阻塞我的 Gunicorn 工作进程吗?

我读了这个问题,但我不确定我的线程是否干扰了“Worker 的主循环”: Danger to having long lasting (non-deamon) threads in a Django/Gunicorn app?

【问题讨论】:

  • BigWig 队列正在您的 LAN 中运行,对吗?我无法想象它要花那么多时间。考虑记录“发送到队列”时间。如果它总是很快,那么不要打扰做另一个线程。多线程/进程程序始终是调试的挑战:)
  • @shavenwarthog 它实际上是一个外部托管的队列。完成一个入队调用需要大约 750 毫秒或 0 毫秒...我假设 celery 库在经过这么多空闲时间后被汇集并关闭的入队时懒惰地打开套接字。 /无论如何/我对这个问题的理论和如何实际解决它同样感兴趣:)
  • 嗯。所以问题是,如果您有线程 A(即:来自 Gunicorn),并且您创建了子线程 B(“发送数据”线程),如果您希望线程 A 返回但线程 B 正忙,会发生什么情况?我不知道。我通常以最简单的方式写东西,等待一切。如果后面不够快,可以优化。非常常见的任务足够快,或者整个项目都消失了:)

标签: python django multithreading gunicorn


【解决方案1】:

没有。 Gunicorn worker 主线程产生的线程没有什么特别之处。

一旦你产生了一个线程,它将并行执行,直到完成或死亡。 Gunicorn 不知道这些从工作主线程产生的线程,因此它不会尝试加入它们,因此工作主线程不会等待子线程完成。此外,线程的守护进程没有任何影响; daemon 只是意味着线程不会对进程的“活跃性”做出贡献,并且会一直运行到进程退出,然后它会被自动杀死。

如果您想在重新使用同一个工作线程之前等待这些线程完成,您必须在 WSGI 应用程序(例如django.core.handlers.wsgi.WSGIHandler.__call__())返回之前执行此操作。或者为 Gunicorn 编写一些疯狂的猴子补丁来跟踪子线程。

TL;DR 您绝对可以通过从工作主线程生成长时间运行的子线程来不受限制地增长线程。最好保证它们会在超时的时间内完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-05
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2013-03-25
    • 2013-03-01
    • 2012-09-09
    • 1970-01-01
    相关资源
    最近更新 更多