Two ways for rabbitmq to consume 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 message of registering the consumer to the queue server through rpc. After receiving the message, the rabbitMQ Server judges that it is a subscription message according to the content type of the message,
so that when there is a message in the queue in MQ, it will The message is automatically sent out through the socket (long connection) channel.
See methods 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, the data packet (Frame) will be obtained from the socket (FrameHandler) in a loop, and the channel.handleFrame(Frame frame) will be called to process the message.

public void handleFrame(Frame frame) throws IOException {
        AMQCommand command = _command;
        if (command. handleFrame(frame)) { // protocol assemble the message
            _command = new AMQCommand(); // prepare for the next one
            handleCompleteInboundCommand(command);//Processing 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


Each Consumer has a BlockQueue, which is used to buffer the messages obtained from the socket.
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/liyantianmin/article/details/46696029

Guess you like

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