2012-03-02 35 views
7

我要描述的实质上是两个不同系统之间的两阶段提交问题,我正在寻找如何处理它的建议。在我们的Web应用程序中,我们将一些昂贵的/第三方操作(例如发送电子邮件)转移到带外后台工作进程(我们称之为我们的工作基础结构)。两阶段提交 - 如何有效使用我的队列?

要发送电子邮件,我们在数据库中创建了一个电子邮件对象和电子邮件作业。然后,我们必须等待我们的工作监视器收取电子邮件作业并发送它。作业监视器基本上是在闲置时每隔几秒轮询一次数据库。

但是,这会在电子邮件发送中添加一个延迟,并将添加的数据添加到数据库的非法负载中。如果我们可以在电子邮件创建后立即将电子邮件作业放到队列中,那将会更好。

但是,这目前失败的原因有两个。首先,队列通常比网络请求快得多。在Web请求提交数据库事务之前,该电子邮件会被拾取以供处理,因此无法正确生成电子邮件。其次,如果Web请求失败,它将回滚其数据库事务,这意味着电子邮件应该发送而不是。但是,如果已经放入队列中,则不再处于请求的控制之下。

在队列和数据库之间创建两阶段提交是否有很好的策略?作为参考,我们使用RabbitMQ和MySQL与InnoDB表。我提出的一个想法是在数据库事务提交后将电子邮件作业粘贴到队列中,但这会使电子邮件从不会排队。我仍然必须创建一个轮询过程来监视应该发送但不发送的电子邮件。

回答

0

我意识到这是一个晚了几年:)但我想为这个问题添加一些想法。

您可以延迟发送消息以增加作业获取时数据库准备就绪的机会。我从来没有使用过RabbitMQ,但是我发现使用rabbitMQ队列作为延迟队列How to create a delayed queue in RabbitMQ?的例子。您的电子邮件工作仍然需要处理任何未注释的记录,因为延迟不是处理分布式处理的确定性方法。

这就是说,它觉得有空间来改善你的设计。通常服务体系结构在服务之间共享数据库表是一个坏主意。它导致分布式事务和扩展问题。我会尽力确保RabbitMQ消息包含独立于任何其他服务处理电子邮件所需的所有数据。或者如果它需要更多数据,它应该通过ServiceBus请求而不是数据库查询请求该数据。