什么';在Django中为多个SQS使用者启用锁定机制的常见做法,因此我可以是幂等的

什么';在Django中为多个SQS使用者启用锁定机制的常见做法,因此我可以是幂等的,django,background-process,amazon-sqs,Django,Background Process,Amazon Sqs,SQS希望您的应用程序是幂等的,并且我有多个消费者/生产者,其中(即使SQS有一个deliver-once机制),我将有竞争条件创建副本,竞争条件消耗,因为我的消费者通过cron作业运行 我目前的计划是使用Django 1.4select\u for\u update,它将阻止同一行上的其他消费者,执行如下操作: reminders = EmailReminder.objects.select_for_update().filter(id=some_id) if not reminders[0]

SQS希望您的应用程序是幂等的,并且我有多个消费者/生产者,其中(即使SQS有一个deliver-once机制),我将有竞争条件创建副本,竞争条件消耗,因为我的消费者通过cron作业运行

我目前的计划是使用Django 1.4
select\u for\u 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.

有更好的方法处理这个问题吗?

将django芹菜连接到SQS,让它使用celerybeat指定一个定期作业。然后,让celeryd worker在同一队列中任意位置运行。一次只有一个人会拿起一个作业并执行它。不需要在任何级别引入DB锁定

只要你的员工保证在celerybeat启动新任务之前完成当前任务,你就永远不需要锁。现在,如果您认为它们可能重叠,您可以为您的通知引入状态,其中:

  • 任何提醒都会在“未发送”状态下启动
  • 您的celerybeat向队列发送处理未发送电子邮件的请求
  • 一些工人把它捡起来,把所有的东西都抢走了
  • 工作人员立即将所有状态转换为“发送”状态
  • 一次发送一个(或批量发送)
  • 如果发送失败,请将其状态恢复为未发送
  • 对于所有成功过渡到发送的

  • 这样,如果celerybeat在初始批处理中未完成原始作业时触发另一个作业,则不会发送重复的电子邮件。作为额外的奖励,您可以扩展解决方案并分配负载。

    使用AMQP/芹菜而不是cron作业的队列?@PauloScardine目前不打算从SQS切换。:)@保罗斯卡丁哦,我不知道芹菜可以做重复的工作,谢谢!我会进一步调查的。