javadockerdocker-composerabbitmq

RabbitMQ Connection Error: java.net.ConnectException: Connection refused


I have two very simple java applications (publisher-consumer) which connect to RabbitMQ server using connectionFactory.newConnection(...).

My docker-compose.yml looks like this:

services:
  publisher:
    build: ./publisher/
    networks:
      - messaging
    depends_on:
      rabbitmq:
          condition: service_healthy
  consumer:
    build: ./consumer/
    networks:
      - messaging
    depends_on:
      rabbitmq:
          condition: service_healthy
  rabbitmq:
    image: rabbitmq:4.0.4-management-alpine
    networks:
      - messaging
    ports:
      - 5672:5672
      - 5671:5671
      - 15672:15672
      - 4369:4369
      - 25672:25672
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "check_running"]
      interval: 10s
      timeout: 10s
      start_period: 30s
      retries: 3
networks:
  messaging:
    name: messaging
    driver: bridge

When I run this scenario RabbitMQ starts successfully but my Publisher and Consumer throw exception. Here's the error log:

rabbitmq-1   | ...
publisher-1  | Exception in thread "main" java.net.ConnectException: Connection refused
consumer-1   | Exception in thread "main" java.net.ConnectException: Connection refused
consumer-1   |  at java.base/sun.nio.ch.Net.pollConnect(Native Method)
consumer-1   |  at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
consumer-1   |  at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542)
consumer-1   |  at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
consumer-1   |  at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
consumer-1   |  at java.base/java.net.Socket.connect(Socket.java:633)
consumer-1   |  at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:61)
consumer-1   |  at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:69)
consumer-1   |  at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:165)
consumer-1   |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1242)
consumer-1   |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1198)
consumer-1   |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1156)
consumer-1   |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1321)
consumer-1   |  at arkadisahakyan.Consumer.main(Consumer.java:20)
publisher-1  |  at java.base/sun.nio.ch.Net.pollConnect(Native Method)
publisher-1  |  at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
publisher-1  |  at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542)
publisher-1  |  at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
publisher-1  |  at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
publisher-1  |  at java.base/java.net.Socket.connect(Socket.java:633)
publisher-1  |  at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:61)
publisher-1  |  at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:69)
publisher-1  |  at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:165)
publisher-1  |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1242)
publisher-1  |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1198)
publisher-1  |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1156)
publisher-1  |  at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1321)
publisher-1  |  at arkadisahakyan.Publisher.main(Publisher.java:20)
consumer-1 exited with code 1
publisher-1 exited with code 1

As you can see I tried adding healthcheck in my compose file to wait until RabbitMQ starts listenting for connections but it didn't work and the problem remains. The connection hostname is localhost but I also tried InetAddress.getLocalHost().getHostName() and InetAddress.getLocalHost().getHostAddress().


Solution

  • The connection hostname is not gonna be localhost because your publisher/consumer apps and RabbitMQ are running in different containers and your not using host network.

    Even though you are port-forwarding the RabbitMQ ports to the host machine, the publisher/consumer apps don't see those ports, because they are attached to the container network messaging.

    Try changing the connection hostname to rabbitmq.