I'm working in Java with RabbitMQ.
I have two RabbitMQ servers, with same configurations, one is the developing environment and the other one is the production environment.
This is the consumer declaration:
/*
* Connection and channel declaration
*/
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(prop.getProperty("ConnectionURI"));
connection = factory.newConnection();
channel = connection.createChannel();
/*
* Queue declaration and exchange binding
*/
channel.exchangeDeclare(prop.getProperty("printExchange"), "topic", false, false, false, new HashMap<>());
queueName = prop.getProperty("printQueue");
routing_key = "print." + codCliente + "." + idCassa;
channel.queueDeclare(queueName, false, false, false, null);
channel.queueBind(queueName, prop.getProperty("printExchange"), routing_key);
And here it starts to listen on the queue:
JAyronPOS.LOGGER.info("Waiting for a message on the queue -> " + queueName + " with routingkey -> " + routing_key);
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
JAyronPOS.LOGGER.info("This is the received message -> " + queueName + ": " + new String(body, "UTF-8"));
Map<String, Object> headers = properties.getHeaders();
if (envelope.getRoutingKey().equals(routing_key)) {
JAyronPOS.LOGGER.info("Message is for me, because it has my routing key");
channel.basicAck(envelope.getDeliveryTag(), false);
if (headers != null) {
if (headers.containsKey("command")) {
JAyronPOS.LOGGER.info("It's a command!");
JAyronPOS.LOGGER.info(headers.get("command").toString());
if ("requestClose".equals(headers.get("command").toString())) {
ChiusuraFiscaleConfirm confirm = gson.fromJson(new String(body, "UTF-8"), ChiusuraFiscaleConfirm.class);
if (confirm.isCanClose()) {
eseguiChiusuraFiscale();
} else {
JOptionPane.showMessageDialog(null, "Can't close", "Error", JOptionPane.ERROR_MESSAGE);
}
} else {
JAyronPOS.LOGGER.info("Can't handle the message");
}
}
} else {
System.out.println("It's a ticket");
TicketWrapper ticket = gson.fromJson(new String(body, "UTF-8"), TicketWrapper.class);
printTicket(ticket);
}
}else{
JAyronPOS.LOGGER.info("The message isn't for me, because it has the routingkey: "+envelope.getRoutingKey());
}
}
};
channel.basicConsume(queueName, false, consumer);
In the development environment, I have max 5 queues, while in the production environment i have between 150-200 queues.
The messages are sent by the exchange, with a personal routing_key. The number of sent messages is not high (no more than 10 msg/s while stressed).
When I test the consumer on the developing environment, everything is OK:
- I send an RPC call, the server process it and reply. The consumer read the reply and call the proper method. All in about 1-2 seconds.
When I use the software in production environment (I change the environment only by commenting/decommenting a line in a config.properties file), it doesn't work:
- I send the RPC call, the server process it and send the reply on the queue. The consumer never receive the message (but I can see the message developed on the queue by the web administration panel).
Which can be the problem?
EDIT: I noticed that if I send the RPC call, in the RabbitMQ web panel, on the reply queue there is a message under "Deliver" (light blue), while if I send 3-4 RPC calls (same of previous one), after some call, on the reply queue there is a message under Publish (yellow), and the consumer receive the reply.