当两个应用程序都使用嵌入式 activemq 时,如何将 Jms 消息从一个 spring-boot 应用程序发送到另一个

How to send Jms message from one spring-boot application to another when both apps use embedded activemq

我有两个 spring-boot 应用程序。在接收方应用程序的 Application.java 我有:

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    return factory;
}

并在 Receiver.java ...

@JmsListener(destination = "myQueue", containerFactory = "myFactory")
public void receiveMessage(String tradeString) throws JSONException, IOException {
    tradeImpl = new ObjectMapper().readValue(tradeString, TradeImpl.class);
}

在发件人应用程序中我简单地使用:

public void send(trade) {
   String queueName = "myQueue";
   String tradeString = new ObjectMapper().writeValueAsString(trade);
   jmsTemplate.convertAndSend(queueName, tradeString);
}

所以我只是将消息发送到接收方应用程序中指定的队列名称。 我在日志中得到以下内容

Failed to start JMX connector Cannot bind to URL [rmi://localhost:1099>/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi [Root exception is java.rmi.AlreadyBoundException:

我已阅读以下内容post,但并不十分鼓舞人心:

最后是:

But As I mentioned I didn't make this working before and not sure if it is possible. Didn't find in Spring Boot docs explicit message it doesn't work in this combination.

I suspect the idea behind embedded Spring Boot JMS broker is to allow local in memory integration testing only, not to expose embedded JMS brokers to the outside world.

有人知道我想做的事情是否真的可行吗?如果没有,是否有任何关于如何使用嵌入式代理在 spring-boot 应用程序之间实现消息传递的建议?

尝试为 producer 应用程序指定 spring.activemq.brokerUrl=tcp://localhost:61616

这样,嵌入式 ActiveMQ Broker 将被禁用,并且将执行到 61616 端口上启动的另一个连接。

如果您的 2 spring 引导应用程序在同一个 jvm 上,您只需 添加两个中的一个的 application.properties :

spring.activemq.broker-url=vm://localhost

Spring Boot can also configure a ConnectionFactory when it detects that ActiveMQ is available on the classpath. If the broker is present, an embedded broker is started and configured automatically (as long as no broker URL is specified through configuration).

如果您的 2 spring 启动应用程序在 2 个不同的 jvm 上: 在一个 spring 引导应用程序中,您需要:

在pom.xml

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-activemq -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
        <version>1.4.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
    </dependency>

第二个:

在application.properties

spring.activemq.broker-url=tcp://localhost:61616

在pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
</dependency>

如果您有 2 个 jvm,每个应用程序 1 个,默认情况下 spring 启动将仅使用 vm 连接器配置 AMQ,在第一个应用程序中您需要像这样添加 tcp 连接器:

@Bean(initMethod = "start", destroyMethod = "stop")
public BrokerService broker() throws Exception {
    final BrokerService broker = new BrokerService();
    broker.addConnector("tcp://localhost:61616");
    broker.addConnector("vm://localhost");
    broker.setPersistent(false);
    return broker;
}