我正在构建rabbitmq消息和Django应用程序之间的日志桥梁,以将后台任务状态存储在数据库中以供进一步调查/审查,还可以通过Django管理界面重新发布任务。 我想这没什么特别的,只是标准的生产者 - 消费者模式。
问题是,db中缺少某些任务,因此从未执行过。 我怀疑这是因为Consumer会在执行db commit之前收到消息。 所以基本上,从Model.save()返回并不意味着事务已经结束并且整个通信中断。
有什么办法可以解决这个问题吗?也许我可以使用某种post_transaction信号?
提前谢谢。
答案 0 :(得分:0)
这对我来说听起来很脆弱:你有一个网络应用程序发布到队列,然后将初始状态插入数据库。如果消费者在Web应用程序可以提交初始状态之前处理消息会发生什么?
如果网络应用在消费者锁定数据库时尝试插入新状态会怎样?
要解决此问题,Web应用程序应将初始状态添加到消息,并且消费者应该是唯一一个写入数据库的人。
[编辑]您可能还有登录问题。通过将消息放入队列而不修改数据库,检查Web应用程序和使用者之间的比赛是否在日志中产生了相应的错误。
[EDIT2]一些想法:
如何仅显示待处理任务的数量?为此,Web应用程序可以写入表1,消费者可以写入表2,而admin将显示差异。
为什么Web应用程序无法查看消费者在队列中的待处理任务?也许你应该有两个消费者。第一个使用者只是将任务添加到DB,提交然后仅使用新行的主键向第二个使用者发送消息。管理员iface可以在第二个消费者写入时读取该表。
最后的想法:在排队邮件之前提交事务。为此,您只需向数据库发送“commit”即可。它会感觉很奇怪(我当然不建议任何情况)但是在这里,手动提交新行可能是有意义的(即在返回处理正常事务逻辑的框架之前)。
答案 1 :(得分:0)
Web应用程序发布到消息队列并将初始任务状态插入数据库
不要这样做。
Web应用程序发布到队列中。完成。通过模板显示结果并完成Web事务。
消费者从队列中取出并执行操作。例如,它可能会附加到数据库的日志以呈现给用户。消费者也可以在执行时向数据库发布其他状态。
实际上,许多应用程序具有多个具有多个产品/消费者关系的队列。每个进程都可以将事物附加到日志中。
然后,演示文稿必须汇总日志条目。通常,最后一个是足够的摘要,但有时您需要先前条目中的计数或信息。