繁体   English   中英

消息排队模式

[英]message queuing patterns

我们有两个架构。 实质上,它们形成了生产者和消费者。 第1部分(p1)将消息发布到处理消息的第2部分(第2页),此过程涉及将消息发送到远程节点,该消息必须在消息处理完消息后对其进行处理,此过程最多可能需要几秒钟。

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

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

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

另一个解决方案可能是p1可以更改为继续尝试将消息发送到p2。 这个问题是p1中的生产者需要在尝试发送下一条消息之前有一个休眠x的线程,显然可能有一个处理这种睡眠/重试机制的单例,但是这里的逻辑,生产者和消费者增加到成千上万,变得相当复杂;

  • 添加,删除,生成器同步
  • 阅读队列,进行下一次阅读时间
  • 低生产者计数时紧密循环的考虑因素
  • 高生产者数量时长时间等待的考虑因素
  • ......等

我接近建议一个MQ层,其中p1发布到,p2读取。 然而,这引入了一个新问题,其中p2在远程节点消失时无法通知p1,但是这可以通过从p2到p1的http回调来处理 - 这里的开销水平是可接受的,因为远程节点的可能性是离开很低。

我错过了一个设计模式,它将不再需要MQ(另一个服务需要担心,监控等)? 非常感谢。

其他一些细节:

  • 每个p1生成器实例大部分都是请求作用域
  • 每个p2使用者都是一个专用的运行线程

麦克风,

看起来这个过程有很大的复杂性(有可能引入更多)只是为了避免使用MQ? 根据我的经验,可能有很多理由不使用MQ,但是如果你有权使用它,那就放弃使用它! :)它比监视代码以引入类似功能更容易监视新的MQ进程。

理想情况下,强大的队列会阻止P1真正需要了解P2或其状态。

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

它还引入了额外的复杂性 - 你知道你的环境,但它可能导致诸如“为什么我不再收到消息?”之类的问题。 - 事实证明服务自动关闭另一项服务。 做得好,这很棒,减轻了操作员的支持负担 - 做错了,只会增加更多的支持负担。 没有人喜欢那个人。

您是否也可以在数据层排队,P2的存储可能不是一个问题?

拥抱队列(MQ,MSMQ,Sql Queue)!

ž

回顾3种可能性

  • 那么为服务命令打开另一个MQ(而不是http调用);
  • 认为p2是多线程的,其中一个没有等待的线程从MQ中提取消息,并将它们放到另一个线程进行处理;
  • (!)使用MQ的事务版本 - 所以p2可以立即提取消息,p1可以尽可能快地放置它。 但是如果处理失败,队列将被回滚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM