java - RabbitMQ使用者不接收消息

时间:2016-05-13 14:31:39

标签: java rabbitmq

我正在用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呼叫(与前一个呼叫相同),在一些呼叫之后,在回复队列上有一条消息在发布(黄色)下,消费者收到回复。

1 个答案:

答案 0 :(得分:0)

您尚未提供发布代码或拓扑,因此很难猜测拓扑的工作原理。

但是在消费者上匹配路由密钥是个坏主意,交易所应该为你做。消费者可以为所需的路由键创建和绑定队列。 在消费者的代码else分支中,不承认或拒绝消息,这可能导致它挂起delivered状态,永远不会被其他消费者接收。

Rabbitmq教程包含有用的RPC部分https://www.rabbitmq.com/tutorials/tutorial-six-java.html