【问题标题】:Differences between UWSGI and Gunicorn when running async calls运行异步调用时 UWSGI 和 Gunicorn 之间的差异
【发布时间】:2016-10-22 03:59:35
【问题描述】:

我有一个 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 以及更长的 threading.Thread 版本时,情况确实如此:

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,所以我问的更多是出于好奇。

谢谢,

【问题讨论】:

    标签: django asynchronous nginx uwsgi gunicorn


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 感谢您的回答!我相信这是我在使用 uWSGI 时遇到的问题。添加 --enable-threads 似乎可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2013-04-02
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多