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

时间:2016-06-20 19:23:33

标签: 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 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_asynchronous函数永远不会被调用。使用after_response以及更长的线程时也是如此。线程版本:

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)。开始()

再次,与开发服务器和#34; runserver"一起使用,也适用于gunicorn,但不适用于uwsgi,我有点疑惑为什么会发生这种情况。使用uwsgi,我实际上从 init 中看到了print语句,但是没有看到run方法中的print语句,当然也没有看到电子邮件。由于这个问题,我已经转而使用gunicorn了,所以我更多的是出于好奇而提出要求。

谢谢,

1 个答案:

答案 0 :(得分:2)

您没有发布您的uWSGI配置,但考虑到这是关于未运行的后台线程,您在启动uWSGI时很有可能need to add --enable-threads

  

如果没有线程启动uWSGI,Python GIL就不会   启用,因此应用程序生成的线程永远不会运行。您   可能不喜欢那个选择,但要记住uWSGI是一个   与语言无关的服务器,所以它的大部分选择都是为了   保持它“不可知”。

     

但不要担心,uWSGI基本上没有选择   无法通过选项更改的开发人员。

     

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