Design patterns 消息队列模式

Design patterns 消息队列模式,design-patterns,architecture,Design Patterns,Architecture,我们有两块建筑。从本质上说,它们构成了生产者和消费者。工件1(p1)将消息发布到工件2(p2),工件2(p2)处理消息,此过程涉及将消息发送到远程节点,远程节点必须在处理完消息后确认消息,此过程最多可能需要几秒钟 p2在其队列中具有有限长度,并且在从远程节点接收到ack之前不会移除项目。因此,p2可以向p1返回队列_完整响应。当p1收到此响应时,它会保留一个队列,每当产生新消息时,它会将其添加到此队列的末尾,然后在队列中循环发送消息到p2,直到它再次将队列_填满。这里的问题是,一旦p2的队列为空

我们有两块建筑。从本质上说,它们构成了生产者和消费者。工件1(p1)将消息发布到工件2(p2),工件2(p2)处理消息,此过程涉及将消息发送到远程节点,远程节点必须在处理完消息后确认消息,此过程最多可能需要几秒钟

p2在其队列中具有有限长度,并且在从远程节点接收到ack之前不会移除项目。因此,p2可以向p1返回队列_完整响应。当p1收到此响应时,它会保留一个队列,每当产生新消息时,它会将其添加到此队列的末尾,然后在队列中循环发送消息到p2,直到它再次将队列_填满。这里的问题是,一旦p2的队列为空/有空间,它就无法通知p1生成消息

对于p2中的每个生产者实例,p1中都有一个对应的生产者,这对于下面的潜在解决方案非常重要

一种解决方案是,p2可以更改为在其队列中有空间时通知p1,但是此解决方案需要相当数量的网络开销(http),因为在任何时候都可能有数千个p2队列需要通知其相应的p1生产者

另一种解决方案是,可以将p1更改为继续尝试向p2发送消息。问题是,p1中的生产者需要有一个休眠x的线程,然后再尝试发送下一条消息,很明显,可能有一个单独的线程来处理这个休眠/重试机制,但是这里的逻辑,随着生产者和消费者增加到数千,变得相当复杂

  • 添加、删除和删除生产者时的同步
  • 读取队列,进行下一次读取
  • 低生产商计数时的紧循环注意事项
  • 高生产者计数时长等待的注意事项
  • 。。。。等
我几乎建议使用一个MQ层,其中p1发布到,p2从中读取。然而,这引入了一个新的问题,即当远程节点离开时,p2无法通知p1,但是这可以通过从p2到p1的http回调来处理-由于远程节点离开的可能性很低,这里的开销水平是可以接受的

我是否缺少一种设计模式,可以消除对MQ(还有另一个需要担心的服务、监视器等)的需求?我非常感激你的想法

其他一些细节:

  • 每个p1 producer实例在大多数情况下都是请求范围
  • 每个p2使用者都是一个专用的运行线程
审查3种可能性

  • 如何为服务命令打开另一个MQ(而不是http调用)
  • 考虑p2是多线程,其中一个线程不等待从MQ提取消息,并将其放置到另一个线程进行处理
  • (!)使用MQ的事务性版本-这样p2可以立即提取消息,p1可以尽可能快地放置消息。但若处理失败,队列将回滚
审查3种可能性

  • 如何为服务命令打开另一个MQ(而不是http调用)
  • 考虑p2是多线程,其中一个线程不等待从MQ提取消息,并将其放置到另一个线程进行处理
  • (!)使用MQ的事务性版本-这样p2可以立即提取消息,p1可以尽可能快地放置消息。但若处理失败,队列将回滚
      迈克

      为了避免使用MQ,这个过程似乎有很大的复杂性(有可能引入更多的复杂性)?根据我的经验,不使用MQ可能有很多原因,但如果您可以访问MQ,请尽情使用它!:)监视新的MQ进程要比编写代码来引入类似的功能容易得多

      理想情况下,健壮的队列将防止P1真正需要了解P2或其状态

      MQ还应该真正减少P2通知P1其远程节点已关闭的需要—P1可以继续愉快地将消息排队发送给P2(取决于消息频率/大小/存储限制)。如果远程节点停机很长时间,则希望这是一个计划中的事件,操作员可以关闭P1。P2和P1之间的管理通道听起来很不错

      它还引入了额外的复杂性—您知道您的环境,但它可能会导致诸如“为什么我不再收到消息?”之类的问题—结果是一个服务自动关闭另一个服务。做得好,这是可怕的,减轻了运营商的支持负担——做得不对,只会增加更多的支持负担。没人喜欢那个家伙

      您是否也可以在数据层排队,因为P2的存储可能不是什么大问题

      拥抱队列(MQ、MSMQ、Sql队列)

      Z

      迈克

      为了避免使用MQ,这个过程似乎有很大的复杂性(有可能引入更多的复杂性)?根据我的经验,不使用MQ可能有很多原因,但如果您可以访问MQ,请尽情使用它!:)监视新的MQ进程要比编写代码来引入类似的功能容易得多

      理想情况下,健壮的队列将防止P1真正需要了解P2或其状态

      MQ还应该真正减少P2通知P1其远程节点已关闭的需要—P1可以继续愉快地将消息排队发送给P2(取决于消息频率/大小/存储限制)。如果远程节点停机很长时间,则希望这是一个计划中的事件,操作员可以关闭P1。P2和P1之间的管理通道听起来很不错

      它还引入了额外的复杂性-您了解您的环境,但它可能会导致诸如“为什么我不再收到消息?”之类的问题