【问题标题】:Why is this simple Flask script taking so long to run?为什么这个简单的 Flask 脚本需要这么长时间才能运行?
【发布时间】:2019-07-02 04:35:50
【问题描述】:

这只是一个在提交表单后发送邮件的脚本:

@application.route('/contact', methods=['GET', 'POST'])
def send():
    if request.method == 'POST':
        first_name = request.form['first_name']
        last_name = request.form['last_name']
        email = request.form['email']
        msg = Message('Hey!', sender='example@example.com', recipients=['example@example.com'])
        msg.body = email + " " + first_name + " " + last_name + " "
        mail.send(msg)
        msg2 = Message('Hello', sender='example@example.com', recipients=[email])
        msg2.body = "Hi " + first_name + ". Thanks for requesting access to our beta. We'll contact you soon to schedule a call."
        mail.send(msg2)

        return render_template('contact.html')

    return render_template ('index.html')

两封电子邮件都已送达,但处理脚本的时间太长,导致注册人数减少。怎么了?

以防万一,我将这个 Flask 应用程序托管在 Elastic Beanstalk 实例上。

【问题讨论】:

    标签: amazon-web-services flask amazon-elastic-beanstalk


    【解决方案1】:

    发送电子邮件是一项需要时间的操作。如果启用日志,您可以看到进行了多次调用。 这与 AWS 或您的服务器无关。

    发送电子邮件应该是您的烧瓶应用程序中的asynchronous 任务。

    有很多方法可以做到这一点。 您可以简单地重构您的代码并使用 @async 装饰器编写一个函数,flask mega tutorial 的详细信息非常好。

    #[...other imports...]
    from threading import Thread
    
    def async(f):
        def wrapper(*args, **kwargs):
            thr = Thread(target=f, args=args, kwargs=kwargs)
            thr.start()
        return wrapper
    
    @async
    def send_async_email(app, msg):
        with app.app_context():
            mail.send(msg)
    
    @application.route('/contact', methods=['GET', 'POST'])
    def send():
        if request.method == 'POST':
            first_name = request.form['first_name']
            last_name = request.form['last_name']
            email = request.form['email']
            msg = Message('Hey!', sender='example@example.com', recipients=['example@example.com'])
            msg.body = email + " " + first_name + " " + last_name + " "
            send_async_email(application, msg)
            msg2 = Message('Hello', sender='example@example.com', recipients=[email])
            msg2.body = "Hi " + first_name + ". Thanks for requesting access to our beta. We'll contact you soon to schedule a call."
            send_async_email(application, msg)
    
            return render_template('contact.html')
    
        return render_template ('index.html')
    

    由于您在 AWS 上运行应用程序,因此您也可以使用 SES 代替 Flask-Mail。

    其他解决方案是使用message queue,例如 RabbitMQ,但这需要编写更多代码。

    所有这些解决方案都会在后台发送电子邮件,让您的烧瓶应用程序向客户端返回响应,而无需等待电子邮件发送。

    【讨论】:

    • 谢谢!我只想说,根据您的建议,我将时间从 30 秒减少到 10 秒。然后我才意识到我可以将信息推送到 DynamoDB 表中,最终将时间缩短到 1 秒。没想到后台发邮件这么复杂!
    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    相关资源
    最近更新 更多