Django 运行异步调用时UWSGI和Gunicorn之间的差异

Django 运行异步调用时UWSGI和Gunicorn之间的差异,django,asynchronous,nginx,uwsgi,gunicorn,Django,Asynchronous,Nginx,Uwsgi,Gunicorn,我有一个Django应用程序,在我的一个视图中,我实际上在对发送电子邮件的函数进行异步调用。我既使用了threading.thread(带start()),也使用了一个名为after_response的小django包,它的作用基本相同 以下是我所做的: def my_synchronous_function(instance): send_email_asynchronous.after_response(instance.id) return "We are done her

我有一个Django应用程序,在我的一个视图中,我实际上在对发送电子邮件的函数进行异步调用。我既使用了threading.thread(带start()),也使用了一个名为after_response的小django包,它的作用基本相同

以下是我所做的:

def my_synchronous_function(instance):
    send_email_asynchronous.after_response(instance.id)
    return "We are done here, but async call will continue."

@after_response.enable
def send_email_asynchronous(instance_id):
    time.sleep(5)
    print "Async has started"
    instance = Instance.objects.get(pk=instance_id)
    subject = "A subject"
    ctx = {'username': instance.username}
    message = get_template("email-template.html").render(ctx)
    msg = EmailMessage(subject, message, to=[instance.email], from_email='loic@example.com')
    print "about to send email"
    time.sleep(5)
    msg.content_subtype = 'html'
    msg.send()
    print "message sent"
运行django manage.py runserver时,此代码非常有效;使用nginx+gunicorn时,它也可以正常工作。但是,我注意到,在使用UWSGI和Nginx时,从未调用send_email_异步函数。这在使用after_响应以及较长的线程时是正确的。线程版本:

class SendNotification(threading.Thread):
    """
    Sends notifications async.
    """
    def __init__(self, instance_id):
        """
        Sends notifications asynchronously provided an instance id.
        """
        print "instance id: %s" % instance_id
        self.instance = Instance.objects.get(pk=instance_id)
        super(SendNotification, self).__init__()

    def run (self):
        time.sleep(5)
        print "Async has started"
        subject = "A subject"
        ctx = {'username': self.instance.username}
        message = get_template("email-template.html").render(ctx)
        msg = EmailMessage(subject, message, to=[self.instance.email],                              from_email='loic@example.com')
        print "about to send email"
        time.sleep(5)
        msg.content_subtype = 'html'
        msg.send()
        print "message sent"
这将通过以下方式启动: SendNotification(instance.id).start()

同样,与开发服务器“runserver”配合使用也很好,与gunicorn配合使用也很好,但与uwsgi配合不好,我对为什么会发生这种情况感到有点困惑。使用uwsgi,我实际上看到了init中的print语句,但没有看到run方法中的print语句,当然也没有电子邮件。由于这个问题,我转而使用gunicorn,所以我问这个问题更多是出于好奇


谢谢,

您没有发布您的uWSGI配置,但考虑到这是关于后台线程未运行,启动uWSGI时您很有可能:

如果在没有线程的情况下启动uWSGI,pythongil将不会被激活 已启用,因此应用程序生成的线程将永远不会运行。你 可能不喜欢这个选择,但请记住uWSGI是一个 独立于语言的服务器,因此它的大多数选择都是针对 保持它的“不可知论”

但别担心,uWSGI基本上没有做出任何选择 无法使用选项更改的开发人员

如果希望在不启动的情况下维护Python线程支持 对于应用程序的多个线程,只需添加--enable线程 选项(或在ini样式中启用threads=true)


您没有发布您的uWSGI配置,但考虑到这是关于后台线程未运行的,启动uWSGI时您很有可能:

如果在没有线程的情况下启动uWSGI,pythongil将不会被激活 已启用,因此应用程序生成的线程将永远不会运行。你 可能不喜欢这个选择,但请记住uWSGI是一个 独立于语言的服务器,因此它的大多数选择都是针对 保持它的“不可知论”

但别担心,uWSGI基本上没有做出任何选择 无法使用选项更改的开发人员

如果希望在不启动的情况下维护Python线程支持 对于应用程序的多个线程,只需添加--enable线程 选项(或在ini样式中启用threads=true)


谢谢你的回答!我相信这就是我和uWSGI之间的问题。添加--enable线程似乎可以做到这一点。谢谢你的回答!我相信这就是我和uWSGI之间的问题。添加--enable线程似乎可以做到这一点。