I'm trying to deploy ActiveMQ Artemis with Spring Boot and Docker. Artemis plus Spring Boot works fine. I'm using spring-boot-maven-plugin
to generate a fat jar. When I try to deploy that fat jar into Docker I see that acceptor is started:
AMQ221020: Started EPOLL Acceptor at localhost:61616 for protocols [CORE]
But I'm not able to connect to it from outside of Docker.
Exception in thread "main" ActiveMQConnectionTimedOutException[errorType=CONNECTION_TIMEDOUT message=AMQ119013: Timed out waiting to receive cluster topology. Group:null]
I'm using this command to run it into Docker:
docker run -p 61616:61616 8bd9ff19ea08
Any idea?
Here the pom.xml
:
<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 http://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.5.6</version>
</parent>
<groupId>SpringBootArtemis2</groupId>
<artifactId>SpringBootArtemis2</artifactId>
<name>Spring Boot Artemis Starter</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.source>1.8</java.source>
<spring.boot.version>2.5.6</spring.boot.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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The Spring boot configuration file:
@Configuration
@EnableJms
public class SpringBootExampleConfiguration {
@Bean
public ArtemisConfigurationCustomizer customizer() {
return new ArtemisConfigurationCustomizer() {
@Override
public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) {
try {
configuration.addAcceptorConfiguration("netty", "tcp://localhost:61616");
}
catch (Exception e) {
throw new RuntimeException("Failed to add netty transport acceptor to artemis instance", e);
}
}
};
}
}
The SpringBootApplication file:
@SpringBootApplication
public class SpringBootExampleMain {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootExampleMain.class, args);
}
}
The docker file:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/SpringBootArtemis2-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
EXPOSE 61616
The consumer code:
ServerLocator locator = ActiveMQClient.createServerLocator("tcp://localhost:61616");
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession();
ClientProducer producer = session.createProducer("example");
ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeString("Hello");
session.createQueue("example", "example", true);
ClientConsumer consumer = session.createConsumer("example");
producer.send(message);
session.start();
ClientMessage msgReceived = consumer.receive();
System.out.println("message = " + msgReceived.getBodyBuffer().readString());
session.close();
I have a different setup exposing OpenWire as well and I have the same behaviour: working fine without docker but not working with docker
The connections are failing because the netty acceptor is listening on localhost so it can only accept connections from processes running on the same host/container.
To fix this issue the SpringBootExampleConfiguration should set the netty acceptor to listen on 0.0.0.0, i. e.
configuration.addAcceptorConfiguration("netty", "tcp://0.0.0.0:61616");
Docker makes deploying microservice applications very easy but it has some limitations for a production environment. I would take a look to the open source ArtemisCloud.io project, it is a collection of container images that provide a way to deploy the Apache ActiveMQ Artemis Broker on Kubernetes.