我们有两个架构。实质上,它们形成了生产者和消费者。第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的需求(另一项服务需要担心,监控等)?非常感谢。
其他一些细节:
答案 0 :(得分:3)
麦克,
似乎这个过程有很大的复杂性(有可能引入更多)只是为了避免使用MQ?根据我的经验,可能有很多理由不使用MQ,但是如果你有权使用它,那就放弃使用它! :)监视新MQ进程要比编写引入类似功能的代码容易得多。
理想情况下,强大的队列会阻止P1真正需要了解P2或其状态。
MQ还应该真正减少P2通知P1其远程节点发生故障的需要 - P1可以继续愉快地将消息排队到P2(取决于消息频率/大小/存储限制)。如果远程节点停机了很长时间,那么希望这是一个计划的事件,操作员可以关闭P1。 P2和P1之间的管理通道听起来很不错?
它还引入了额外的复杂性 - 你知道你的环境,但它可能导致诸如“为什么我不再收到消息?”之类的问题。 - 事实证明服务自动关闭另一项服务。做得好,这很棒,减轻了操作员的支持负担 - 做错了,只会增加更多的支持负担。没有人喜欢那个人。
您是否也可以在数据层排队,P2的存储可能不是一个问题?
拥抱队列(MQ,MSMQ,Sql Queue)!
ž
答案 1 :(得分:1)
回顾3种可能性