Analysis of two ways (poll, subscribe) for RabbitMQ Consumer to obtain messages

In rabbitMQ, the consumer creates a channel object by establishing a connection to the queue, and obtains the message through the channel channel. The consumer
can declaratively obtain messages from the queue by polling the API, or passively from the queue by subscribing. Consuming news,
I recently read the relevant source code of the Java-based client and made a simple analysis.
The programming model pseudocode is as follows:
ConnectionFactory factory = new ConnectionFactory();
Connection conn = factory.newConnection();
Channel channel=conn.createChannel();
To create a Connection, you need to specify the physical address and port of MQ, which is a socket tcp physical connection, and Channel is a logical concept that supports the creation of multiple MQ channels on tcp connections.
The following are two consumption methods based on channels.

1. Subscribe subscription method
boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "myConsumerTag",
     new DefaultConsumer(channel) {
         @Override
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body)
             throws IOException
         {
             String routingKey = envelope.getRoutingKey();
             String contentType = properties.contentType;
             long deliveryTag = envelope.getDeliveryTag();
             // (process the message components here . ..)
             channel.basicAck(deliveryTag, false);
         }
     });

The subscription method is actually to register the consumer with the queue, and send the registered consumer message to the queue server through rpc. After receiving the message, the rabbitMQ Server judges according to the content type of the message This is a subscription message,
In this way, when there is a message in the queue in MQ, the message will be automatically sent out through the socket (long connection) channel.
See the method in ChannelN
    public String basicConsume(String queue, boolean autoAck, String consumerTag,
                               boolean noLocal, boolean exclusive, Map<String, Object> arguments,
                               final Consumer callback)
        throws IOException
    {
    ......
        rpc((Method)
            new Basic.Consume.Builder()
             .queue(queue)
             .consumerTag(consumerTag)
             .noLocal(noLocal)
             .noAck(autoAck)
             .exclusive(exclusive) .arguments
             (arguments)
            .build(),
            k);

        try {
            return k.getReply();
        } catch(ShutdownSignalException ex) {
            throw wrap(ex);
        }
    }

The process of the Consumer receiving the message:
After the Connection is created, the MainLoop background thread will be started, looping from the socket (FrameHandler) Get the data packet (Frame), call channel.handleFrame(Frame frame) to process the message,
    public void handleFrame(Frame frame) throws IOException {
        AMQCommand command = _command;
        if (command.handleFrame(frame)) { // assemble the message
            _command = new AMQCommand(); // prepare for the next one
            handleCompleteInboundCommand(command);//Process message consumption
        }
    }
ChannelN.handleCompleteInboundCommand
       ---ChannelN.processAsync
           ----dispatcher.handleDelivery
                 ---
                     QueueingConsumer.handleDelivery ---this._queue.add(new Delivery(envelope, properties, body));//The message is finally put into the queue for
each Consumer There is a BlockQueue for buffering messages obtained from sockets.
Next, the Consumer object can call the api to obtain messages from the _queue cached by the client in turn and consume them. See QueueingConsumer.nextDelivery()

For this long connection method, the heartbeat function is not seen to prevent long connection. The connection fails due to network and other reasons.


2. The poll API method
ChannelN:
GetResponse basicGet(String queue, boolean autoAck)
This method is relatively simple, and directly obtains the messages in the queue from the MQ Server side through RPC

Reference : http://blog.csdn. net/yangbutao/article/details/10395599

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326876789&siteId=291194637