Home > Java > body text

Spring Boot embedded ActiveMQ Artemis broker connection

WBOY
Release: 2024-02-11 13:39:08
forward
824 people have browsed it

php editor Banana introduces you to Spring Boot embedded ActiveMQ Artemis proxy connection. ActiveMQ Artemis is a high-performance, scalable message broker often used to build reliable messaging systems. Spring Boot provides a simple and convenient way to integrate ActiveMQ Artemis. Through embedded connections, we can use ActiveMQ Artemis directly in Spring Boot applications without additional configuration and deployment. This connection method not only simplifies the development process, but also provides higher performance and reliability, making message delivery more efficient and stable. Whether you are developing real-time applications, message queues, or asynchronous communications, Spring Boot embedded ActiveMQ Artemis broker connection is an option worth exploring.

Question content

I have a very simple spring boot 2.7.6 activemq artemis application that listens for messages.

package hello;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.context.annotation.bean;
import org.springframework.jms.annotation.jmslistener;
import org.springframework.jms.annotation.enablejms;
import org.springframework.jms.config.defaultjmslistenercontainerfactory;
import org.springframework.boot.autoconfigure.jms.defaultjmslistenercontainerfactoryconfigurer;
import javax.jms.connectionfactory;
import org.springframework.jms.config.jmslistenercontainerfactory;

@springbootapplication
@enablejms
public class application {

    @bean
    public jmslistenercontainerfactory<?> myfactory(connectionfactory connectionfactory,
                            defaultjmslistenercontainerfactoryconfigurer configurer) {
      defaultjmslistenercontainerfactory factory = new defaultjmslistenercontainerfactory();
      // this provides all auto-configured defaults to this factory, including the message converter
      configurer.configure(factory, connectionfactory);
      // you could still override some settings if necessary.
      return factory;
    }

    public static void main(string[] args) {
       springapplication.run(application.class, args);
    }

    @jmslistener(destination = "my-queue-1")
    public void listen(string in) {
       system.out.println(in);
    }
}
Copy after login

This is the code to configure the embedded proxy. I'm just guessing by adding multiple receivers. Different posts reference addconnectorconfiguration, but so far none of them seem to work.

package hello;

import org.apache.activemq.artemis.api.core.transportconfiguration;
import org.apache.activemq.artemis.core.remoting.impl.netty.nettyacceptorfactory;
import org.apache.activemq.artemis.core.remoting.impl.netty.nettyconnectorfactory;
import org.springframework.boot.autoconfigure.jms.artemis.artemisconfigurationcustomizer;
import org.springframework.context.annotation.configuration;


@configuration
public class artemisconfig implements artemisconfigurationcustomizer {
    @override
    public void customize(org.apache.activemq.artemis.core.config.configuration configuration) {
      configuration.addacceptorconfiguration("remote", "tcp://0.0.0.0:61616");
    }
}
Copy after login

With this simple application.properties:

spring.artemis.mode=embedded
spring.artemis.embedded.server-id=54321
spring.artemis.embedded.queues=my-queue-1
spring.artemis.embedded.enabled=true
Copy after login
Copy after login

Then I have another spring boot application that generates messages and sends them to the proxy address.

package broker.producer;

import org.apache.activemq.artemis.jms.client.activemqconnectionfactory;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.value;
import org.springframework.context.annotation.bean;
import org.springframework.jms.core.jmstemplate;
import org.springframework.jms.support.destination.jndidestinationresolver;
import org.springframework.stereotype.service;

@service
public class jmsproducer {

  @value("${spring.jms.template.default-destination}")
  private string defaultdestination;

  logger log = loggerfactory.getlogger(jmsproducer.class);

  @bean
  public activemqconnectionfactory activemqconnectionfactory() {
      activemqconnectionfactory activemqconnectionfactory = new activemqconnectionfactory("tcp://localhost:61616");

      return activemqconnectionfactory;
  }

  @bean
  public jndidestinationresolver jndidestinationresolver() {
    return new jndidestinationresolver();
  }

  @bean
  public jmstemplate jmstemplate() {
    jmstemplate template = new jmstemplate();
    template.setconnectionfactory(activemqconnectionfactory());
    template.setpubsubdomain(false); // false for a queue, true for a topic
    template.setdefaultdestinationname(defaultdestination);

    return template;
  }


  public void send(string message) {
    jmstemplate jmstemplate = jmstemplate();

    log.info("sending message='{}'", message);
    jmstemplate.convertandsend(message);
    log.info("sent message='{}'", message);
  }
}
Copy after login

Then I start each application and try to call the send method, but I can't connect to the broker from the producer application because of this error:

2024-01-16 10:25:00.596 ERROR 30486 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]] with root cause
Copy after login

The producer application is able to connect to the docker instance of activemq artemis just fine.

Currently, both applications are running on the same machine, but in production I would like each application to run in a separate pod.

Workaround

I put together a very simple project as a proof of concept to make sure what you are doing is possible and everything is working fine for me. The embedded agent is started and accepting connections from remote clients on port 61616.

This is application.java:

package hello;

import javax.jms.connectionfactory;
import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.boot.autoconfigure.jms.defaultjmslistenercontainerfactoryconfigurer;
import org.springframework.context.annotation.bean;
import org.springframework.jms.annotation.enablejms;
import org.springframework.jms.annotation.jmslistener;
import org.springframework.jms.config.defaultjmslistenercontainerfactory;
import org.springframework.jms.config.jmslistenercontainerfactory;

@springbootapplication
@enablejms
public class application {

    @bean
    public jmslistenercontainerfactory<?> myfactory(connectionfactory connectionfactory,
                                                                    defaultjmslistenercontainerfactoryconfigurer configurer) {
        defaultjmslistenercontainerfactory factory = new defaultjmslistenercontainerfactory();
        // this provides all auto-configured defaults to this factory, including the message converter
        configurer.configure(factory, connectionfactory);
        // you could still override some settings if necessary.
        return factory;
    }

    public static void main(string[] args) {
        springapplication.run(application.class, args);
    }

    @jmslistener(destination = "my-queue-1")
    public void listen(string in) {
        system.out.println(in);
    }
}
Copy after login

This is artemisconfig.java:

package hello;

import org.springframework.boot.autoconfigure.jms.artemis.artemisconfigurationcustomizer;
import org.springframework.context.annotation.configuration;


@configuration
public class artemisconfig implements artemisconfigurationcustomizer {
    @override
    public void customize(org.apache.activemq.artemis.core.config.configuration configuration) {
       try {
          configuration.addacceptorconfiguration("remote", "tcp://0.0.0.0:61616");
       } catch (exception e) {
          e.printstacktrace();
       }
    }
}
Copy after login

This is my application.properties:

spring.artemis.mode=embedded
spring.artemis.embedded.server-id=54321
spring.artemis.embedded.queues=my-queue-1
spring.artemis.embedded.enabled=true
Copy after login
Copy after login

Finally, this is my pom.xml:

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelversion>4.0.0</modelversion>
   <parent>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-parent</artifactid>
      <version>2.7.6</version>
      <relativepath/>
   </parent>
   <groupid>com.example</groupid>
   <artifactid>spring-boot-customized-activemq-artemis</artifactid>
   <version>0.0.1-snapshot</version>
   <properties>
      <java.version>17</java.version>
      <spring.version>2.7.6</spring.version>
      <activemq.artemis.version>2.19.1</activemq.artemis.version>
   </properties>

   <dependencies>
      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-artemis</artifactid>
      </dependency>
      <dependency>
         <groupid>org.apache.activemq</groupid>
         <artifactid>artemis-jms-server</artifactid>
     <version>${activemq.artemis.version}</version>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-maven-plugin</artifactid>
        <version>${spring.version}</version>
         </plugin>
      </plugins>
   </build>
</project>
Copy after login

I launch the application like this:

mvn spring-boot:run
Copy after login

I saw this log record:

...
... AMQ221020: Started EPOLL Acceptor at 0.0.0.0:61616 for protocols [CORE]
... AMQ221007: Server is now live
...
Copy after login

I can send a message to the broker from another application and jmslistener will receive the message.

I have uploaded the project to github.

The above is the detailed content of Spring Boot embedded ActiveMQ Artemis broker connection. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template