考虑以下场景:
假设有 4 个微服务,每个微服务应该有自己的队列。让我们使用下面的场景
- 微服务 A --> 队列.A
- 微服务 B --> 队列.B
- 微服务 C --> 队列.C
- 微服务 D --> 队列.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 请求,表示“嗨,我已经启动,为我创建一个队列并将其与主队列绑定(bind)”。
微服务 B 启动并执行相同的操作。
到目前为止,我所做的是通过 java API 调用创建代理,并通过 java 方法和类配置虚拟目标和复合队列,如下所示:
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);
上面的代码位于 BrokerService
@Configuration 类内部的 bean。
当 springboot 应用程序(代理)启动时,它会创建上述 child.queue 并将其与 master.queue 绑定(bind)(一切都很好且完美),但即使在代理设置完成后我也想执行上述操作。
为此,我创建了一个小型服务类和一个 Controller 类,并将上面的代码放入一个名为 createQueue(String queueName)
的方法中。并在我的 Controller 中使用它。
当访问该端点时,没有任何反应。没有错误,没有警告,代码被执行但没有反射(reflect)在代理中。我无法看到新创建的队列,并且将消息发送到主队列不会将其转发到子队列。
这种情况有可能吗?在运行时配置和制作复合队列?
最佳答案
事实证明他们的在线文档不一致。 在这个问题(https://activemq.apache.org/what-is-the-difference-between-a-virtual-topic-and-a-composite-destination)中,它明确指出了以下陈述:
The main difference between a Virtual Topic and a Composite Desetination is that with a Composite Destination the list of consumer destinations is static and hard wired. Whereas with a Virtual Topic at run time a new consumer or queue can be created dynamically and addded to the subscription without having to reconfigure the broker.
但是!在此页面中,包含版本 5.9 的发行说明 (https://activemq.apache.org/runtime-configuration),其中指出某些标记是运行时可配置的。 文档应始终保持一致。
附:以防万一有人想做:
您必须添加 <runtimeConfigurationPlugin checkPeriod="1000" />
在代理配置中并使用此属性 start="false"
在主经纪商标签内。
关于java - activemq 代理启动后是否可以创建虚拟目的地和复合队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60320891/