【发布时间】:2020-06-04 20:02:32
【问题描述】:
考虑以下场景:
假设有 4 个微服务,每个微服务都应该有自己的队列。让我们使用下面的场景
- 微服务 A --> queue.A
- 微服务 B --> queue.B
- 微服务 C --> queue.C
- 微服务 D --> queue.D
现在上述所有微服务都应该将消息发送到主队列,我们称之为 queue.master。当微服务 A 想向微服务 B 发送消息时,它会将消息发送到主队列,主队列会将其路由到微服务 B,依此类推。换句话说,没有微服务队列知道彼此的队列,它只知道主队列,主队列将相应地“路由”消息。
现在问题出在上述场景的配置上。
对于基于 XML 的,这将是相当简单和直接的。
我将定义一个<destinationInterceptors> 标签以及<compositeQueue> 和<forwardOnly> 标签,如下所示:
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="queue.master" forwardOnly="false">
<forwardTo>
<queue physicalName="queue.A" />
<queue physicalName="queue.B" />
<queue physicalName="queue.C" />
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
我还将在标签中使用选择器,以便它可以“过滤”出消息并相应地发送它们。 上述基于 XML 的方案按预期工作。 但我希望在程序执行期间也使用上述配置。 基本上我想做的是:
代理即将启动
微服务 A 启动,将向代理发送消息或 Web 请求,说“嗨,我起来了,为我创建一个队列并将其与主队列绑定”。
微服务 B 启动并执行相同的操作。
到目前为止,我所做的是通过 java API 调用创建代理,并通过 java 方法和类配置 virtualdestination 和复合队列,如下所示:
VirtualDestinationInterceptor virtualDestinationInterceptor = new VirtualDestinationInterceptor();
CompositeQueue compositeQueue = new CompositeQueue();
Queue queue = new ActiveMQQueue("queue.A"); // create the child queue of microservice
compositeQueue.setName("master.queue"); // the master queue .
compositeQueue.setForwardTo(Arrays.asList(queue));
virtualDestinationInterceptor.setVirtualDestinations(new VirtualDestination[]{compositeQueue});
DestinationInterceptor[] destinationInterceptors = new DestinationInterceptor[]{virtualDestinationInterceptor};
brokerService.setDestinationInterceptors(destinationInterceptors);
上面的代码位于 @Configuration 类中的 BrokerService bean。
当 springboot 应用程序(代理)启动时,它会创建上面的 child.queue 并将其与 master.queue 绑定(一切都很好而且完美)但是即使在代理设置之后我也想执行上述操作。
为此,我创建了一个小型服务类和一个控制器类,并将上述代码放入一个名为 createQueue(String queueName) 的方法中,并在我的控制器中使用它。
当访问该端点时,什么也没有发生。没有错误没有警告,代码被执行但它没有反映在代理中。我看不到新创建的队列,并且将消息发送到主队列并没有将其转发到子队列。
这种情况甚至可能吗?在运行时配置和制作复合队列?
【问题讨论】:
标签: java spring jms activemq messagebroker