python - 异步芹菜任务开销
问题描述
我正在使用此代码为数千封电子邮件发送通知。似乎它在运行 for 循环之后在 Web 服务器(gunicorn)中产生了一些开销。发送电子邮件时一切正常。
users = User.query.all()
for user in users:
send_email_celery(user.email, gettext(u'New email'), 'users/email/new_data', #plus some parameters)
所以我正在考虑使用密件抄送,但后来我意识到我不能,因为每个用户都有一个唯一的 uuid 退订并且密件抄送在邮件客户端中有一些限制。
那么,使用批量邮件处理此类操作的正确方法是什么?
@celery.task
def send_async_email_celery(msg):
mail.send(msg)
def send_email_celery(to, subject, template, **kwargs):
countdown = kwargs.get('countdown', 600)
app = current_app._get_current_object()
msg = Message(subject, sender=app.config['MAIL_SENDER'], recipients=[to])
msg.html = render_template(template + '.html', **kwargs)
send_async_email_celery.apply_async(args=[msg], countdown=countdown)
gunicorn --error-logfile gunicorn-error.log --timeout 600 --max-requests 500 --max-requests-jitter 50 --workers 5 app:app -b localhost:8080
编辑 1:使用 top 进行一些调试后,cpu 未满载。是在几秒钟内暂时停止gunicorn的其他东西。
编辑 2:根据 2ps 的答案进行更改后,现在循环很快,但在循环执行几秒钟后,Web 服务器仍被锁定。
编辑3:尝试将rabbitmq更改为reddis,同样的问题。忽略结果,同样的问题。
编辑4:将用户循环移动到@celery 路由后,问题仍然存在
编辑 5:该问题已通过使用 gevent worker 解决。
解决方案
html 电子邮件渲染是开销——如果您想让调用者更快地完成此操作,请将模板渲染移动到 celery 任务中。
@celery.task
def send_async_email_celery(subject, from_, to_, template, **kwargs):
msg = Message(subject, sender=from_, recipients=[to_])
msg.html = render_template(template + '.html', **kwargs)
mail.send(msg)
def send_email_celery(to, subject, template, **kwargs):
countdown = kwargs.get('countdown', 600)
app = current_app._get_current_object()
from_ = app.config['MAIL_SENDER']
send_async_email_celery.apply_async(args=[subject, from_, to, template], kwargs=kwargs, countdown=countdown)
推荐阅读
- html - How to process 2 of click events in order in Angular
- macos - 在 influxdb 中编辑 Meta.db
- java - 如何通过在球衣中添加自定义标头从请求过滤器发送响应
- testing - 需要帮助识别 testcafe 中的元素
- c# - ASP.NET CORE 2.1 跨线程模拟
- python - 使用 dtype 读取二进制文件会导致 ValueError
- asp.net - 请求过滤模块,用于拒绝查询字符串过长的请求
- c# - 问题是在 Windows 7 中为 UBL Api 安装 .pem 扩展安全证书
- c# - xml反序列化不绑定列表
- flutter - 边框半径不适用于容器小部件内