Design patterns 消息队列模式
我们有两块建筑。从本质上说,它们构成了生产者和消费者。工件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的线程,然后再尝试发送下一条消息,很明显,可能有一个单独的线程来处理这个休眠/重试机制,但是这里的逻辑,随着生产者和消费者增加到数千,变得相当复杂Design patterns 消息队列模式,design-patterns,architecture,Design Patterns,Architecture,我们有两块建筑。从本质上说,它们构成了生产者和消费者。工件1(p1)将消息发布到工件2(p2),工件2(p2)处理消息,此过程涉及将消息发送到远程节点,远程节点必须在处理完消息后确认消息,此过程最多可能需要几秒钟 p2在其队列中具有有限长度,并且在从远程节点接收到ack之前不会移除项目。因此,p2可以向p1返回队列_完整响应。当p1收到此响应时,它会保留一个队列,每当产生新消息时,它会将其添加到此队列的末尾,然后在队列中循环发送消息到p2,直到它再次将队列_填满。这里的问题是,一旦p2的队列为空
- 添加、删除和删除生产者时的同步
- 读取队列,进行下一次读取
- 低生产商计数时的紧循环注意事项
- 高生产者计数时长等待的注意事项
- 。。。。等
- 每个p1 producer实例在大多数情况下都是请求范围
- 每个p2使用者都是一个专用的运行线程
- 如何为服务命令打开另一个MQ(而不是http调用)李>
- 考虑p2是多线程,其中一个线程不等待从MQ提取消息,并将其放置到另一个线程进行处理李>
- (!)使用MQ的事务性版本-这样p2可以立即提取消息,p1可以尽可能快地放置消息。但若处理失败,队列将回滚李>
- 如何为服务命令打开另一个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之间的管理通道听起来很不错
它还引入了额外的复杂性-您了解您的环境,但它可能会导致诸如“为什么我不再收到消息?”之类的问题