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.
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); } }
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"); } }
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
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); } }
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
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.
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); } }
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(); } } }
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
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>
I launch the application like this:
mvn spring-boot:run
I saw this log record:
... ... AMQ221020: Started EPOLL Acceptor at 0.0.0.0:61616 for protocols [CORE] ... AMQ221007: Server is now live ...
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!