我们今天的流程是;多个服务器将消息发送到 ActiveMQ 队列,并且带有
MDB
的 maxSession=100
(消费者)轮询该队列。 MDB
读取消息并将消息传递给其他第三方 REST 服务。
一些第三方 REST 服务对我们的
MDB
及其 REST 服务一次可以拥有的并行连接数有限制。因此,由于 maxSession=100
,如果连续多条消息应该发送到同一个第三方 REST 服务,我们可以打破此限制。
我想到了一些可能的解决方案(好的和坏的):
拒绝消息并按照预定的延迟将其放回到队列中
这似乎是最前沿的解决方案,我们使用消息,检查是否已达到该 REST 服务的并行连接阈值,如果是,我们将按计划的延迟将消息添加回队列。但这有明显的问题,例如可能多次读取一条消息,并且我们不知道正确的延迟是什么。
多个队列
我们有超过一千个不同的 REST 服务要发送到,为每个服务都有一个 MDB 和队列是不切实际的。
浏览消息后手动消费消息
我们可以先检查队列,检查队列上的消息有哪些
@MessageDriven
,而不是使用 MDB keys
自动消费消息,然后只消费带有 key
/messageSelector
没有的消息达到了门槛。但这似乎需要大量编码。
根据
messageSelector
限制活动消息的数量
我不知道这是否可行,但如果可能的话,这似乎是一个很好的解决方案。
通常如何处理此限制?
此类情况通常通过重新投递来处理。 ActiveMQ Artemis 支持与延迟相关的重新交付的多个不同参数,这样您就不会最终破坏后端 REST 服务。
我建议在 MDB 中使用容器管理的事务,如果后端 REST 服务拒绝您的请求,则只需将该事务标记为仅回滚并从您的
onMessage
返回即可。这将立即释放 MDB 来处理另一条可能不受任何阻塞/限制的消息。
重新交付在概念上很简单,需要很少的代码,并且通常很有效。如果此解决方案不起作用,您可以稍后研究更复杂的解决方案。在您知道自己确实需要它之前,增加复杂性没有任何好处。