SQS希望你的应用程序是幂等的,我有多个消费者/生产者(即使SQS有一次交付机制)我会有竞争条件造成重复和竞争条件消耗,因为我的消费者通过cron作业运行。
我目前的计划是使用Django 1.4 select_for_update
,它应该阻止同一行中的其他消费者,执行以下操作:
reminders = EmailReminder.objects.select_for_update().filter(id=some_id)
if not reminders[0].finished:
reminder.send()
reminder.update(finished=datetime.now())
# Delete job.
有没有更好的方法来解决这个问题?
答案 0 :(得分:3)
将django-celery连接到SQS并让它使用celerybeat指定一个定期工作。然后让celeryd worker在任何你想要的队列上运行。只有一个人会一次拿起一份工作并执行它。无需在任何级别引入数据库锁定。
只要您的工作人员在celerybeat发射新任务之前保证完成当前任务,您将永远不需要锁定。现在,如果您认为它们可能会重叠,您可以在以下位置介绍通知状态:
这样,如果celerybeat在原始作业未完成初始批处理时触发另一个作业,则不会发送重复的电子邮件。作为额外的奖励,您可以扩展解决方案并分配负载。