Python 高手编程系列一千零九十六:使用任务队列和延迟处理

有时它不是做很多,而是在正确的时间做事情。一个很好的例子是在 Web 应用程序中
发送电子邮件。在这种情况下,增加的响应时间可能不一定是由你的实现导致。响应时间
可能受到某些第三方服务(例如电子邮件服务器)影响。如果你只是花大部分时间等待其
他服务回复,你能否优化你的应用程序呢?
答案可以为是,也可以为否。如果你对一个服务没有任何控制,而这个服务是处理时
间的主要贡献者,并且你没有其他更快的解决方案可以使用,当然,你无法进一步的加快
它。你不能简单地跳过你正在等待的答复的时间。处理 HTTP 请求中发送电子邮件的一个
简单示例如图 12-1 所示。你不能减少等待时间,但你可以改变用户的感知方式!
解决这种类型的问题的惯用模式是使用消息/任务队列。当你需要执行耗时不确定的操
作时,只需将其添加到处理它的工作队列中,并立即响应接受请求的用户即可。在这里,
我们来到为什么发送电子邮件是这样一个很好的例子。电子邮件已经是任务队列!如果使
用 SMTP 协议向电子邮件服务器提交新邮件,则响应成功并不意味着你的电子邮件已投递给收件人。这意味着电子邮件已传送到电子邮件服务器,稍后它将尝试进一步投递。
因此,如果来自服务器的响应不能保证电子邮件是完全投递的,你不需要为了为用户
生成 HTTP 响应而等待它。使用任务队列的处理请求流程如图 12-2 所示。
当然,你的电子邮件服务器可能响应极快,但你需要一些更多的时间来生成需要发送
的消息。也许你正在生成 XLS 格式的年度报告,或者可能以 PDF 文件投递发票。如果使
用已经异步的电子邮件传输,则将整个消息生成任务也放入消息处理系统。如果你不能保
证确切的投递时间,那么你不应该为同步生成投递的消息而费心。
在应用程序的关键部分正确地使用任务/消息队列还可以给你带来其他好处。
• 为 HTTP 请求提供服务的 Web 工作者可以从额外的工作中解脱出来,从而可以更快地
处理请求。这意味着你可以使用相同的资源处理更多的请求,从而处理更大的负载。
• 消息队列通常更不受外部服务的瞬时故障的影响。例如,如果你的数据库或电子邮
件服务器不时地超时,你可以始终将当前处理的任务重新排队,并稍后重试。
• 通过良好的消息队列实现,你可以轻松地在多台计算机上分配工作。这种方法可以
提高一些应用程序组件的可扩展性。
向应用程序添加异步任务处理不可避免地增加了整个系统架构的复杂
性。你将需要设置一些新的后台服务(一个消息队列,如 RabbitMQ),并创建能够处理这些
异步作业的工作者。幸运的是,已经有一些流行的工具可以用于构建分布式任务队列。在
Python 开发人员中最受欢迎的是 Celery(参见 http://www.celeryproject.org/)。它是一个完整
的任务队列框架,支持多个消息服务器,也允许计划执行任务(它可以替代您的 cron 作业)。
如果你需要更简单的东西,那么 RQ(参见 http://pythonrq.org/)可能是一个很好的选择。它
比 Celery 简单得多,并使用 Redis 键/值存储作为其消息服务器(RQ 实际上代表 Redis 队列)。
虽然有一些好的并且经过实战检验的工具,你应该总是仔细考虑你的任务队列的方法。
绝不能把每种类型的工作都放到队列中处理。它们善于解决几种类型的问题,但也会引入
一堆新的问题。
• 增多的系统架构复杂性。
• 处理不止一次交付。
• 维护和监控更多的服务。
• 更大的处理延迟。
• 难以记录日志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值