Hot questions for Using RabbitMQ in docker

Question:

I am trying to dockerize my Java application which tries to connect to a Rabbitmq server. I have passed the Rabbitmq Url via docker env variable and readig the same url using

System.getenv("RABBITMQ_URL")

, but it came out to be null. Is there anything wrong with the way I am reading the docker env variable ? Here is my Docker create command :

docker service create --name xxx --env RABBITMQ_URL=amqp://rabbitmq:xxxx --network msgq --with-registry-auth ${imageName}


Answer:

This is weird but, restarting the docker container just worked fine for me. Turns out , i have to restart the container when ever I update the network connection using "--network". Thanks

Question:

I have a java app running in a docker container and a rabbitmq running in local host (mac). The app need to communicate with the rabbitmq on local host, could some one point out how could i achieve this?


Answer:

Docker engine provide a virtual network interface as a getway if you use --net="bridge". It's a standard value. On linux you can know the name of the interface with ifconfig command.

docker0   Link encap:Ethernet  IndirizzoHW 02:42:56:6c:95:26  
      indirizzo inet:172.17.0.1  Bcast:0.0.0.0  Maschera:255.255.0.0
      indirizzo inet6: fe80::42:56ff:fe6c:9526/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:28267 errors:0 dropped:0 overruns:0 frame:0
      TX packets:25451 errors:0 dropped:0 overruns:0 carrier:0
      collisioni:0 txqueuelen:0 
      Byte RX:52948314 (52.9 MB)  Byte TX:25718113 (25.7 MB)

Inside my container I just use, in this case, 172.17.0.1 as gateway to access to my host.

Inside your container you can also show routes with the route command and see what is the default gateway

root@15fae92c516f:/# route
 Kernel IP routing table
 Destination     Gateway         Genmask         Flags Metric Ref    Use      Iface
 default         172.17.0.1      0.0.0.0         UG    0      0        0  eth0
 172.17.0.0      *               255.255.0.0     U     0      0        0  eth0
root@15fae92c516f:/# 

Question:

I try to run simple test project with technologies I wrote above, but got weird exception and can't find a solution. I use windows 7 and docker works on host: 192.168.99.100. Admin panel of rabbitmq by adress http://192.168.99.100:15672, working good.

Application properties:

spring.rabbitmq.host=192.168.99.100
spring.rabbitmq.port=15672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
jsa.rabbitmq.queue=jsa.queue

Component:

@Component
public class Consumer {

    @RabbitListener(queues="${jsa.rabbitmq.queue}")
    public void recievedMessage(String msg) {
        System.out.println("Recieved Message: " + msg);
    }
}

StackTrace:

2019-09-14 16:00:54.677 ERROR 4532 --- [68.99.100:15672] c.r.c.impl.ForgivingExceptionHandler     : An unexpected connection driver error occured

    java.net.SocketException: Socket Closed
        at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.8.0_201]
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) ~[na:1.8.0_201]
        at java.net.SocketInputStream.read(SocketInputStream.java:171) ~[na:1.8.0_201]
        at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[na:1.8.0_201]
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) ~[na:1.8.0_201]
        at java.io.BufferedInputStream.read(BufferedInputStream.java:265) ~[na:1.8.0_201]
        at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:288) ~[na:1.8.0_201]
        at com.rabbitmq.client.impl.Frame.readFrom(Frame.java:91) ~[amqp-client-4.0.2.jar:4.0.2]
        at com.rabbitmq.client.impl.SocketFrameHandler.readFrame(SocketFrameHandler.java:164) ~[amqp-client-4.0.2.jar:4.0.2]
        at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:571) ~[amqp-client-4.0.2.jar:4.0.2]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

Why the host was read partly and how can I handle it?


Answer:

RabbitMQ brokers listen on port 5672 by default, so change your configuration to use 5672 instead of the management console port 15672:

spring.rabbitmq.port=5672

Reference:

Question:

I am running RabbitMQ in the Docker container. In addition to RabbitMQ image I also installed RabbitMQ management plugin.

Using plugin I created user 'executor'. I set user permissions to

 
Virtual host / 
Configure regexp    .* 
Write regexp    .* 
Read regexp     .*

Here is my code

public static void main(String[] argv)  throws Exception {
     String message;
     ConnectionFactory factory = new ConnectionFactory();
     factory.setHost(SERVER);
     factory.setUsername(RABBIT_USER);
     factory.setPassword(RABBIT_USER_PASSWORD);
     Connection connection = factory.newConnection();
     Channel channel = connection.createChannel();
     channel.queueDeclare(QUEUE_NAME, IS_DURABLE_QUEUE, false, false, null);

     message = argv.length==1?argv[0]:"Hello World!";
     channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
     System.out.println(" [x] Sent '" + message + "'");
     channel.close();
     connection.close();
}

When I run this app I get the following exception

Exception in thread "main" com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:362)
    at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:64)
    at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:134)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:997)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:956)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:914)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1068)
    at ca.meh.hial.producer.Producer.main(Producer.java:24)

Clearly user can't connect due to authentication issues.

I am not sure if I need to install some other plugin. Or do I need to configure Docker container to validate credentials?


Answer:

Apparently you can't use management console from one Docker container to manage RabbitMQ in another Docker container.

Question:

I have an Application which is running on Tomcat, java 8 and Linux. I have managed to port the application to Docker Container and run Tomcat on Docker. I have realized that when A message which is being send to RabbitMQ is not being fetched by the Application on the first initially and instead there should Always be a second Message in the same Queue in order for the Consumer to fetch them both from Queue.

The application is written on Spring 4 and RabbitMQ is outside of container. Frustrating part is that the same application works when I run the application on a VM while the consumer will Fetch when there is more than One message in the Queue. The prefetch is set to 1 and same config works on VM Linux. however On Docker this does not work. Are you guys aware of such issue on Docker containers?

The rabbitMQ management is showing me there is 0 Ready, 1 UnAcked and 1 In total. Could the be the behaviour of JVM on Docker?

Here is an example of log from AMQP Spring:

Retrieving delivery for Consumer@3a6237b3: tags=[{amq.ctag-DRCYJkVeEnTtN94Yuk-7dw=dispatcher.all}], channel=Cached Rabbit Channel: AMQChannel(amqp://user@192.168.1.5:5672/DEV-CI,17), conn: Proxy@45e9797b Shared Rabbit Connection: SimpleConnection@43eb454d [delegate=amqp://user@192.168.1.5/DEV-CI, localPort= 60354], acknowledgeMode=AUTO local queue size=0|BlockingQueueConsumer:nextMessage:499|Pool-Executor-18

Here is the screenshot from the rabbitmq manager:

Docker container:

  • linux: 16.04
  • java:8
  • tomcat:8
  • RabbitMQ 3.6.5, Erlang 18.3
  • Spring-amqp version: 1.7.6.RELEASE
  • Docker Engine: 17.12.0-ce

Answer:

The issue was caused by ThreadPoolTaskExecutor and the thread was being recalled every minutes. To solve the issue I removed setting Executor on RabbitMQ Connection Factory. connectionFactory.setExecutor(asyncTaskExecutor); is removed The connectionFactory is CachingConnectionFactory

Probably I can continue tune the ThreadPoolTaskExecutor to enhance the behaviour. Following is the details of threadpool

corePoolSize = 1;

maxPoolSize = Integer.MAX_VALUE;

queueCapacity = 1;

setWaitForTasksToCompleteOnShutdown(true);