Spring AMQP Source Analysis 04-messagelistener

Source: Internet
Author: User
Tags thread class rabbitmq

# # Ready# # Target Understand how Spring AMQP implements asynchronous message delivery (push mode) # # PRE-Knowledge "RABBITMQ Getting started _05_ multithreading consuming the same queue"# # Related Resources Quick Tour for the Impatient: gordon.study.rabbitmq.springamqp.AsyncConsumer. Java

# # # analysis # # MessageListenerOrg.springframework.amqp.core.MessageListeneris the listener interface for Spring AMQP asynchronous message delivery, which has only one method, OnMessage, to handle messages that are pushed by Message Queuing. MessageListener probably corresponds to the Consumer class in the AMQP client. The OnMessage method probably corresponds to the Handledelivery method of the Consumer class. It can also be seen that the message class of Spring AMQP contains at least consumer tag, envelope, basic properties, and message body, etc. # # MessagelistenercontainerOrg.springframework.amqp.rabbit.listener.MessageListenerContainerCan be seen as a container for message linstener. But the semantics of this Container does not mean that it contains multiple message listener, which are actually seen in the method annotations and implementation code.Messagelistenercontainer contains only a single MessageListener。 What is the semantics of that Container? On the one hand, Container refers toAlthough there is only one messagelistener that specifies the logic for message consumption, multiple threads can be generated using the sameMessageListener consume messages at the same time . The 19th line of code setconcurrentconsumers method is used to specify the number of concurrent consumers. You can think of Messagelistenercontainer as the Subscriber group.
On the other hand, Containerrepresenting the responsibilities of life cycle management。 MessageListener only implements the message consumption logic, and the whole time when the message consumption begins, when it ends, how it is set up, what the state is, and so on, is the responsibility of Messagelistenercontainer (and its implementation class). As a matter of factMessagelistenercontainerinherit fromthe Smartlifecycle interface, which is a lifecycle management-related interface provided by the spring container, in which the class that implements the interface is typically started and stopped by the spring container. Because the Spring container environment is not enabled in this example, the 26th line of code needs to invoke the start method proactively, and message consumption will start executing. # # Internal Implementation Ideaswe know that the Consumer interface in the AMQP client actually defines only the callback method, and we are in the callback method (mainlyHandledeliveryMethod) to implement their own business logic (consumption of messages). The callback method of the Consumer interface is actually executed in a separate thread, and when we call the Channel's basicconsume method, the AMQP client creates a thread to process the message and creates a queue cache message to be pushed from the broker. However, these internal implementations are not exposed, resulting in Spring AMQP having to rewrite a similar implementation on its own to get maximum flexibility.  According to the previous analysis, we can imagine Spring AMQP in order to implement its own message listener, which components are required:
  • Messagelistenercontainer implementation class, i.e. Org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer . It exists as the core class for the entire asynchronous message delivery.
  • Because Messagelistenercontainer actually manages a consumer thread group, the related thread classes and thread scheduling classes are required. this thread class is org.springframework.amqp.rabbit.listener.simplemessagelistenercontainer$ in Spring AMQP Asyncmessageprocessingconsumer, the Dispatch class is of course the Simplemessagelistenercontainer, whose start method starts the thread
  • Messages that are pushed over Message Queuing require a local queue cache.
  • The Consumer interface for the AMQP client needs to be implemented. In this interface implementation class, we simply put the message in the local queue. Org.springframework.amqp.rabbit.listener.blockingqueueconsumer$internalconsumer is in charge of this thing.
  • According to the principle of single responsibility, thread class is responsible for the creation of asynchronous consumers and (infinite loop) message consumption; Internalconsumer is only responsible for implementing the Consumer interface of the AMQP client, docking with the AMQP client native asynchronous message delivery, Put the message in the local queue. Well, we also need a real asynchronous consumer model to manage consumer behavior and state. Org.springframework.amqp.rabbit.listener.BlockingQueueConsumer undertake this part of the responsibility. As can be seen from the name,Blockingqueueconsumer uses blockingqueue as the local queue cache message .
  • The user's business logic is implemented in the MessageListener interface, and the main process of the framework is to create the appropriate connection and channel, get the message from the AMQP client to the local cache, read the message from the local cache , and Invoke The OnMessage method of the MessageListener interface consumes messages.

# # Internal Process AnalysisSimplemessagelistenercontainerOfStartMethod is based onint Concurrentconsumersvalue to create the corresponding number ofBlockingqueueconsumerinstance, and putset<blockingqueueconsumer> ConsumersIn Then for eachBlockingqueueconsumer create a corresponding message processing thread Asyncmessageprocessingconsumer(implements the Runnable interface), and Executor taskexecutor = new Simpleasynctaskexecutor () this self-implementing thread pool starts each asyncmessageprocessingconsumer thread. Finally, judging whether the fatallistenerstartupexception startupexception property of each asyncmessageprocessingconsumer has a value Simplemessagelistenercontainer All message listeners are started normally.  There are many constructor parameters for building Blockingqueueconsumer , where ConnectionFactory is the 17th line of code created Cachingconnectionfactory,acknowledgemode default to AUTO . Org.springframework.amqp.core.AcknowledgeModeThree confirmation modes are defined:
    • None: Not confirmed, equivalent to the Autoack parameter value set to True in the Channel.basicconsume method in the AMQP client
    • MANUAL: User manually control message acknowledgement via channel Aware listener
    • The auto:spring AMQP framework determines whether message consumption is determined based on whether an exception is thrown during the execution of the onMessage of the messages listener
 Asyncmessageprocessingconsumer 's Run method is more complex, a rough interpretation of
  1. Call the Blockingqueueconsumer start method (not the Runnable interface).
  2. The Start method is first passed connectionfactoryutils. The gettransactionalresourceholder static method creates a channel for the thread to use, and the return type of the method is Rabbitresourceholder. This part of the code involves transactions, very complex, but the test code of this article does not involve transactions, so long as the understanding of multiple Asyncmessageprocessingconsumer will generate multiple Rabbitresourceholder instances, but because of the use of Cachingconnectionfactory the default cache mode, so these Rabbitresourceholder instances share the same (AMQP) connection, each Asyncmessageprocessingconsumer Exclusive access to one (AMQP) channel created by this connection
  3. Start MethodThen createInternalconsumerinstance, and calls the AMQP channel that you just created.BasicqosAndBasicconsumemethod to begin accepting messages. This way, when the queue receives the message, the AMQP client actively calls theInternalconsumerOfHandledeliveryMethod. The method callsBlockingQueueConsumer.this.queue.put (New Delivery (Consumertag, envelope, properties, body));Put the message inBlockingqueueconsumerOfblockingqueue<delivery> QueueInOrg.springframework.amqp.rabbit.support.DeliveryClass encapsulates the AMQP client through Handledeliverythe method sends back all the parameters.
    There are two details worth saying: First, Blockingqueueconsumer can consume multiple queues at the same time, and each queue will be calledBasicconsumemethod to letInternalconsumerListens to the current queue (that is,same channel, same Consumer, different queue); second, you can passconsumertagstrategy tagstrategySet Tag naming rules.
  4. Next, call Simplemessagelistenercontainer 's receiveandexecute method in the while loop, trying to get from the queue without stopping Delivery The instance, converts it to a Message, and then executes the messagelistener onMessage callback method.
  5. If the execution succeeds, the Basicack method of calling the AMQP channel confirms that the message was consumed successfully.
  6. If an exception occurs during execution, the exception is converted to listenerexecutionfailedexception thrown. By default, Spring AMQP's logic for handling user-defined exceptions is simple: calling the basicreject method of the AMQP channel returns the message to the queue, prints the warning level of the log, but does not break Asyncmessageprocessingconsumer thread's while loop, message consumption continues. This part of the content of the next article analysis.

Spring AMQP Source Analysis 04-messagelistener

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.