Python 了解使用线程模块发送邮件时的Gunicorn工作进程

Python 了解使用线程模块发送邮件时的Gunicorn工作进程,python,django,multithreading,gunicorn,Python,Django,Multithreading,Gunicorn,在我的设置中,我使用Gunicorn在单CPU机器上进行部署,有三个工作进程。我是从这个答案中提出这个问题的。我有过这样的经历,发送邮件需要一秒半的时间,所以我尝试异步发送电子邮件。我试图了解Gunicorn启动的工作进程将发生什么情况,它将启动一个新线程来发送邮件,该进程是否会被阻止,直到邮件发送线程完成。在这种情况下,我相信我的应用程序的吞吐量会下降。我不想用芹菜,因为设置芹菜只是为了发送电子邮件似乎有点过头了。我目前在同一台机器上运行两个容器,开发机器上有三名gunicorn工人 下面是讨

在我的设置中,我使用Gunicorn在单CPU机器上进行部署,有三个工作进程。我是从这个答案中提出这个问题的。我有过这样的经历,发送邮件需要一秒半的时间,所以我尝试异步发送电子邮件。我试图了解Gunicorn启动的工作进程将发生什么情况,它将启动一个新线程来发送邮件,该进程是否会被阻止,直到邮件发送线程完成。在这种情况下,我相信我的应用程序的吞吐量会下降。我不想用芹菜,因为设置芹菜只是为了发送电子邮件似乎有点过头了。我目前在同一台机器上运行两个容器,开发机器上有三名gunicorn工人

下面是讨论中的方法,唯一的区别是我将使用线程发送邮件

import threading
from .models import Crawl

def startCrawl(request):
    task = Crawl()
    task.save()
    t = threading.Thread(target=doCrawl,args=[task.id])
    t.setDaemon(True)
    t.start()
    return JsonResponse({'id':task.id})

def checkCrawl(request,id):
    task = Crawl.objects.get(pk=id)
    return JsonResponse({'is_done':task.is_done, result:task.result})

def doCrawl(id):
    task = Crawl.objects.get(pk=id)
    # Do crawling, etc.

    task.result = result
    task.is_done = True
    task.save()

假设您使用的是gunicorn Sync(默认)、Gthread或Async worker,那么您确实可以生成线程,gunicorn不会注意到/干扰。这些线程在返回结果后立即被重用以响应以下请求,而不仅仅是在所有线程再次联接之后

我已使用此代码在请求后一分钟左右触发独立事件:

计时器(超时,函数做某事,[参数到函数]).start()

在正常操作中,这些工人在一个循环中运行,直到主人告诉他们关闭或杀死他们。工人将定期向船长发出心跳信号,表明他们仍然活着并在工作。如果心跳超时发生,那么主机将杀死工作进程并重新启动它

因此,不干扰辅助线程主循环的守护线程和非守护线程应该不会产生影响。如果线程确实干扰了工作人员的主循环,例如线程正在执行工作并将向HTTP响应提供结果的场景,那么考虑使用异步工作人员。异步工作进程允许TCP连接长时间保持活动状态,同时仍允许工作进程向主进程发出心跳信号

我最近继续使用基于异步事件循环的解决方案,比如,提供了在线程中等待IO的替代方案