在Django/Gunicorn应用中使用长时间运行的非守护线程有什么风险?

4 投票
1 回答
1562 浏览
提问于 2025-04-17 13:41

我一般在Django应用程序的编程中(比如视图部分)不需要特别使用线程。不过,我发现有一个看起来很有意思的库,它通过线程来处理服务器端的分析。

在Django的视图中,你可以使用他们的Python客户端,在一个单独的(非守护)线程中批量发送HTTP POST请求到他们的网络服务。通常情况下,我会选择RabbitMQ来处理这种事情,而不是使用线程,但他们希望降低这个库的启动成本。

我想问的是,这种方法有没有什么缺点?线程会占用额外的内存,但我对此并不太担心。显然,这取决于启动的请求/线程的数量。

非守护线程可能会长时间运行,这会不会成为问题?我假设Gunicorn进程是执行的主线程,它在一个无限循环中运行,所以如果它需要等待非守护线程结束,通常也没关系,对吧?

这算是一个开放性的问题,但主要是想理解在Django/Gunicorn应用中,非守护线程的影响。

1 个回答

7

Gunicorn使用了一种叫做“预先分叉”的工作模式。它的主进程负责创建和管理工作进程。对于非Tornado的使用场景,工作进程有两种类型:同步工作进程(默认)和异步工作进程

在正常情况下,这些工作进程会一直循环运行,直到主进程告诉它们优雅地关闭或者直接杀掉它们。工作进程会定期向主进程发送“心跳”信号,以表明它们仍然在正常工作。如果心跳信号超时了,主进程就会杀掉这个工作进程并重新启动它。

因此,和工作进程的主要循环没有冲突的守护线程和非守护线程应该不会有影响。如果某个线程干扰了工作进程的主要循环,比如这个线程正在处理工作并将结果返回给HTTP响应,那么可以考虑使用异步工作进程。异步工作进程允许TCP连接保持长时间活跃,同时仍然可以向主进程发送心跳信号。

撰写回答