消息排队消息之间的依赖关系

时间:2013-03-20 13:09:14

标签: multithreading rabbitmq message-queue

以下是我的情景:

  • 我有两台服务器,每台服务器上有一个多线程消息队列消费者(两个消费者总数)。
  • 我有很多消息类型(CreateParent,CreateChild等)
  • 我遇到了糟糕的遗留代码(创建一个孩子会部分创建一个父母。我知道这很糟糕......但我不能改变它。)
  • 不能假设消息排序(消息排队原则!)
  • RabbitMQ是我的消息排队经纪人。

我的问题:

  • 当两个线程同时运行时(一个执行CreateParent,另一个执行CreateChild),它们会产生冲突,因为两个线程尝试在数据库中创建Parent(请记住遗留代码!)

我最初的解决方案:

  • 在消费者中,我创建了一个“实体锁定”概念。因此,当线程处理CreateChild消息时,它会锁定Child和Parent(遗留代码!!),以便CreateParent消息处理可以等待。我使用了基本的.net监视器和ID列表来实现这个概念。效果很好。

我最初的解决方案限制:

  • 我的“实体锁定”概念适用于单个服务器上单个进程中的单个使用者。但它不能在运行多个消费者的多个服务器上运行。
  • 我正在考虑使用共享数据库“存储”我的实体锁定概念,因此每个进程(和线程)都可以访问数据库以验证哪些实体被锁定。

我的问题(终于!):

所有这些都变得非常复杂,它增加了bug风险和代码维护问题。我真的不喜欢它! 有没有人遇到过这种问题?它们是可接受的解决方法吗? 有没有人对我的场景有一个干净的解决方案?

谢谢!

1 个答案:

答案 0 :(得分:1)

最后,简单的解决方案永远是更好的解决方案!

我没有使用“实体锁定”概念的所有复杂性,而是在执行请求之前最终拒绝预先验证所有必需的数据和实体状态。

更确切地说,在遇到CreateParent创建的已有数据时,不是让CreateChild进程自身崩溃,而是在执行CreateChild消息之前完全验证数据库中的一切正常。

此解决方案的缺点是CreateChild的实现必须知道CreateParent将生成什么特定数据,并在开始执行之前验证它的存在。但严重的是,这比锁定跨系统中的所有内容要好得多!