【问题标题】:Is it possible to create virtualDestinations and compositeQueue once the active-mq broker has been started up?启动 activemq 代理后是否可以创建虚拟目的地和复合队列?
【发布时间】:2020-06-04 20:02:32
【问题描述】:

考虑以下场景:

假设有 4 个微服务,每个微服务都应该有自己的队列。让我们使用下面的场景

  1. 微服务 A --> queue.A
  2. 微服务 B --> queue.B
  3. 微服务 C --> queue.C
  4. 微服务 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


    【解决方案1】:

    事实证明,他们的在线文档并不一致。 在这个问题 (https://activemq.apache.org/what-is-the-difference-between-a-virtual-topic-and-a-composite-destination) 中,它明确声明了以下声明:

    虚拟主题和复合主题的主要区别 Desetination 是具有复合目的地的消费者列表 目的地是静态和硬连线。而在虚拟主题 运行时可以动态创建和添加新的消费者或队列 无需重新配置代理即可订阅。

    但是!在此页面中存在版本 5.9 的发行说明 (https://activemq.apache.org/runtime-configuration),它指出某些标签是运行时可配置的。 文档应始终保持一致。

    p.s 以防万一有人想做: 您必须在代理配置中添加&lt;runtimeConfigurationPlugin checkPeriod="1000" /&gt;,并在主代理标记中使用此属性start="false"

    以上参考:https://access.redhat.com/documentation/en-us/red_hat_jboss_a-mq/6.1/html/managing_and_monitoring_a_broker/fmqadminconfigsoloruntime

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多