我正在用RabbitMQ从事Java工作 我有两台RabbitMQ服务器,配置相同,一个是开发环境,另一个是生产环境 这是消费者声明:
/*
* 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);
在这里,它开始收听队列:
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);
在开发环境中,我有最多5个队列,而在生产环境中,我有150到200个队列
消息由交换机使用个人routing_key发送。发送的消息数量不高(强调时不超过10 msg / s)
当我在开发环境中测试消费者时,一切正常:
- 我发送一个RPC调用,服务器处理它并回复。消费者阅读回复并调用正确的方法。全程约1-2秒
当我在生产环境中使用该软件时(我只通过在config.properties文件中注释/删除一行来更改环境),它不起作用:
- 我发送RPC调用,服务器处理它并在队列上发送回复。消费者永远不会收到消息(但我可以看到Web管理面板在队列中开发的消息)。
哪个可能是问题?
编辑:我注意到,如果我发送RPC调用,在RabbitMQ网页面板上的回复队列中,“Deliver”(浅蓝色)下会显示一条消息,而如果我发送3 -4RX呼叫(与前一个呼叫相同),在一些呼叫之后,在回复队列上有一条消息在发布(黄色)下,消费者收到回复。
答案 0 :(得分:0)
您尚未提供发布代码或拓扑,因此很难猜测拓扑的工作原理。
但是在消费者上匹配路由密钥是个坏主意,交易所应该为你做。消费者可以为所需的路由键创建和绑定队列。
在消费者的代码else
分支中,不承认或拒绝消息,这可能导致它挂起delivered
状态,永远不会被其他消费者接收。
Rabbitmq教程包含有用的RPC部分https://www.rabbitmq.com/tutorials/tutorial-six-java.html