【发布时间】: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