我通常发送事务性电子邮件来响应我网站上的某些操作,其中一些我会延迟几个小时发送。实际将邮件排队的函数是一个由.delay()
调用的芹菜任务函数,该函数最终使用djrill
对Mandrill进行API调用。
我发现Mandrill在发送电子邮件时提供了一个send_at
参数,这将使Mandrill延迟发送电子邮件直到指定的时间。当在任务上调用apply_async()
或delay()
时,芹菜也提供了eta
或countdown
参数,这将使芹菜工作程序在执行任务之前等待X时间,这在这里相当于同样的事情。
忽略成本,哪一种方法在架构上更可取:让芹菜使用countdown
延迟排队,或者立即将电子邮件发送给Mandrill,但使用send_at
参数,以便Mandrill等待我?在做这个决定时,我应该考虑哪些因素?
我将在这里分享一些我们在做选择时可以考虑的要点:
-
容错:如果我们把这个责任交给芹菜,那么我们可能更容易失败,因为如果消息队列(Rabbitmq, ZeroMQ或其他),机器或芹菜本身失败,那么电子邮件将永远不会发送。山魈也可能不及格,但可能是小等级。
-
Maintenance:如果您需要将芹菜更改为其他东西怎么办?在这种情况下,您需要迁移代码,并且可能需要花费一些时间来弄清楚如何在新的MQ工具中执行此调度。
-
OOP:从OPP的角度来看,我们可以将Mandrill视为发送电子邮件的实体,它带来了几个功能,例如调度,所以让我们从系统中消费这个外部服务,让它完成它的工作!
-
可用性和可伸缩性:考虑一个假设的情况,由于性能需求不断增长,您需要同时在多个服务器上运行您的系统;哪一种更容易、更有效的方式来处理这个日程安排?
这些并不是做决定时应该考虑的所有方面,但肯定有一些是不应该错过的。