Running ActiveMQ Artemis with Spring Boot on Docker

1.6k Views Asked by At

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

1

There are 1 best solutions below

0
On BEST ANSWER

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.