Message Queuing RABITMQ

Source: Internet
Author: User
Tags ack rabbitmq

Rabbitmq

MQ is all called the message queue, and Message Queuing (MQ) is an application -to-application communication method . Applications communicate by reading and writing messages to and from the queue (data for the application), without requiring a dedicated connection to link them. Message passing refers to the process of communicating between programs by sending data in a message , rather than by directly invoking each other , and directly invoking techniques such as remote procedure calls. Queuing refers to an application communicating through a queue. The use of queues removes the requirement that both the receiving and sending applications execute concurrently .

Usage Scenarios

In the project, some operations without immediate return and time-consuming are extracted and processed asynchronously, which greatly saves the request response time of the server and improves the throughput of the system.

Meaning

RABBITMQ is a reusable enterprise messaging system that is done on an AMQP basis. He follows the Mozilla Public License open source agreement.

Client
Import Com.rabbitmq.client.channel;import Com.rabbitmq.client.connection;import Com.rabbitmq.client.ConnectionFactory; Public classSend {PrivateFinalStaticString queue_name ="Hello";  Public Static voidMain (string[] args) throws. ioexception{ConnectionFactory Factory=NewConnectionFactory (); Factory.sethost ("localhost"); Connection Connection=factory.newconnection (); Channel Channel=Connection.createchannel (); Channel.queuedeclare (Queue_name,false,false,false,NULL); String message="Hello world!"; Channel.basicpublish ("", Queue_name,NULL, Message.getbytes ()); System. out. println ("[x] Sent '"+ Message +"'");  Channel.close ();  Connection.close (); }}
Consumer-side
 Public classRABBITMQRECV { Public Static voidMain (String avg[]) throws. ioexception,java.lang.interruptedexception {ConnectionFactory Factory=NewConnectionFactory (); Factory.sethost ("localhost");
Connection Connection=factory.newconnection (); Channel Channel=Connection.createchannel (); Channel.queuedeclare (Queue_name,false,false,false,NULL);
System. out. println ("[*] waiting for messages. To exit Press CTRL + C"); Queueingconsumer Consumer=NewQueueingconsumer (channel); Channel.basicconsume (Queue_name,true, consumer);
     while(true) {queueingconsumer.delivery Delivery=Consumer.nextdelivery (); String message=NewString (Delivery.getbody ()); System. out. println ("[x] Received '"+ Message +"'"); }}}
Several concepts exchange: A switch that determines the message routing rule; queue: Message queue; channel: Channels for message reading and writing; Bind: Queue and Exchange are bound, which message queue will be placed into what routing rules are met; The structure diagram of the RABBITMQ is as follows:

Several concept notes: Broker: The Message Queuing server entity is simply the case.
Exchange: A message switch that specifies what rules the message is routed to and to which queue.
Queue: A message queue carrier in which each message is put into one or more queues.
Binding: Bind, which is the role of binding exchange and queue according to routing rules.
Routing key: The routing keyword, exchange messages are delivered based on this keyword.
Vhost: Virtual host, a broker can open multiple vhost, as a separate user permissions.
Producer: The message producer is the program that delivers the message.
Consumer: The message consumer is the program that receives the message.
Channel: The message channels, in each connection of the client, multiple channels can be established, each channel represents a session task. The use of Message Queuing is probably as follows: (1) The client connects to the Message Queuing server and opens a channel.
(2) The client declares an exchange and sets the related properties.
(3) The client declares a queue and sets the related properties.
(4) The client uses routing key to establish a good binding relationship between Exchange and queue.
(5) Clients post messages to exchange. When Exchange receives a message, it routes messages to one or more queues based on the key of the message and the binding that has been set. There are several types of exchange, which are delivered entirely according to Key, called do direct Switch, for example, when binding sets the routing key to "ABC", then the client submits a message that only the key "ABC" is set to be posted to the queue. When the key is matched with a pattern, the post is called Topic Switch, the symbol "#" matches one or more words, and the symbol "*" matches exactly one word. For example, "abc.#" matches "Abc.def.ghi", "abc.*" matches only "Abc.def". There's another one that doesn't need a key, called fanout Switch, it takes broadcast mode, and when a message comes in, it is posted to all queues that are bound to the switch. RABBITMQ supports the persistence of messages, that is, data is written on disk, and for data security reasons, I think most users will choose to persist. Message Queuing persistence consists of 3 parts:
(1) Exchange persistence, specifying durable + 1 at the time of declaration
(2) Queue persistence, specify durable when declaring = 1
(3) Message persistence, specifying Delivery_mode = 2 on delivery (1 non-persistent) if both Exchange and queue are persisted, the binding between them is persistent. If there is a persistence between Exchange and queue, a non-persisted, binding is not allowed.

What is MQ?

MQ is all called the message queue, and Message Queuing (MQ) is an application-to-application communication method. MQ is a typical representative of the consumer-producer model, where one end writes messages to the message queue and the other end reads the messages in the queue.

RABBITMQ is a kind of MQ. The basic concepts of RABBITMQ are described in detail below.

1. Queue, producer, consumer

A queue is an internal object of RABBITMQ that is used to store messages. Producers (p in) produce messages and deliver them to the queue, and consumers (c) can get messages from the queue and consume them.

Multiple consumers can subscribe to the same queue, and messages in the queue are distributed evenly across multiple consumers, rather than every consumer receiving all the messages and processing.

2. Exchange, Binding

Just now we've seen the producers deliver the message to the queue, which in fact is never going to happen in RABBITMQ. The actual situation is that the producer sends the message to Exchange (the X in the exchanger), and then associates the exchange with the queue through the binding.


3. Exchange Type, bingding key, routing key

At the same time as binding (binding) Exchange and queue, a binding key is typically specified. These bindings allow the same binding key to be used when binding multiple queues to the same exchange.

When a producer sends a message to exchange, it typically assigns a routing key to specify the routing rules for the message, and the producer can specify routing key to determine where the message flows when sending the message to exchange.

There are three kinds of exchange types commonly used by RABBITMQ: fanout, Direct, topic.

fanout: All messages sent to the exchange are posted to all the queues that are bound to it.

Direct: deliver the message to the queue where the binding key matches the routing key exactly.

Topic: Route the message to the binding key in the queue that matches the routing key pattern.

Attach a RABBITMQ structure diagram:

Finally, to analyze a few specific questions:

1, you can create the queue automatically, you can also create a queue manually, if the queue is created automatically, then who is responsible for creating the queue? Is it a producer? or a consumer?

If the queue does not exist, of course the consumer will not receive any messages. However, if the queue does not exist, the messages sent by the producer will be lost. So, for the data not to be lost, both consumers and producers can create queues. So what if you create a queue that already exists? Then there will be no effect. Note that there is no effect, that is, the second creation if the parameter is different from the first, the operation succeeds, but the queue property does not change.

Queues are perfect for load-balancing processing. For multiple consumers, RABBITMQ is sent to different consumers in a balanced way using polling.

2, RABBITMQ the message confirmation mechanism

By default, if a message has been correctly received by a consumer, the message is removed from the queue. Of course, you can also send the same message to a lot of consumers.

If a queue does not have a consumer, then if the queue has data to arrive, then this data will be cached and will not be discarded. When a consumer is available, the data is immediately sent to the consumer, which is deleted from the queue when the data is received correctly by the consumer.

So what is the right to receive it? by ACK. Each message must be acknowledged (ACK). We can display the ACK in the program, or it can be automatically ack. If there is data not being ACK, then:

RabbitMQ server will send this message to the next consumer.

If the app has bugs and forgets the ACK, then rabbitmqserver no longer sends the data to it because the server thinks the consumer has limited processing power.

And the ACK mechanism can play a limiting role (Benefitto throttling): After the consumer processing data to send an ACK, even after an additional delay to send an ACK, will effectively balance the load of consumers.

Two: code example

2.1: First introduce the RABBITMQ jar package

<dependency>            <groupId>com.rabbitmq</groupId>            <artifactid>amqp-client</ artifactid>            <version>3.6.5</version> </dependency>

2.2: Create consumer producer

/** * Message creator*/ Public classProducer { PublicFinalStaticString queue_name="rabbitmq.test";  Public Static voidMain (string[] args) throws IOException, TimeoutException {//Create a connection factoryConnectionFactory factory =NewConnectionFactory (); //setting RABBITMQ Related informationFactory.sethost ("localhost"); //Factory.setusername ("LP"); //Factory.setpassword (""); //Factory.setport (2088); //to create a new connectionConnection Connection =factory.newconnection (); //Create a channelChannel Channel =Connection.createchannel (); //declares a queue Channel.queuedeclare (Queue_name, False, False, false, NULL);String message ="Hello RabbitMQ"; //send a message to the queueChannel.basicpublish ("", Queue_name,NULL, Message.getbytes ("UTF-8")); System. out. println ("Producer Send + '"+ Message +"'"); //close channels and connectionsChannel.close ();    Connection.close (); }}

Note 1:queuedeclare The first parameter indicates the queue name, whether the second parameter is persisted (true indicates that the queue will survive the server restart), whether the third parameter is an exclusive queue (the private queue that the creator can use, the automatic deletion after disconnection), The fourth parameter is whether the queue is automatically deleted when all consumer client connections are disconnected, and the fifth parameter is the other parameters for the queue

Note 2:basicpublish The first parameter is the switch name, the second parameter is the queue-mapped route key, the third parameter is the other attribute of the message, and the fourth parameter is the body that sends the information

2.3: Create Consumer

public class Customer {private final static String queue_name = "Rabbitmq.test"; public static void Main (string[] args) throws IOException, TimeoutException {//Create connection factory ConnectionFactory FA        Ctory = new ConnectionFactory ();        Set RABBITMQ address Factory.sethost ("localhost");        Create a new connection Connection Connection = Factory.newconnection ();        Create an aisle Channel = Connection.createchannel ();        Declares the queue to be followed Channel.queuedeclare (Queue_name, False, False, true, NULL);        System.out.println ("Customer waiting Received messages"); The Defaultconsumer class implements the Consumer interface by passing in a channel,//telling the server that we need the message for that channel, and if there is a message in the channel, the callback function is executed handledelivery Consumer Consu Mer = new Defaultconsumer (channel) {@Override public void Handledelivery (String consumertag, Envelo PE envelope, AMQP. Basicproperties properties, byte[] body) throws IOException {StRing message = new String (Body, "UTF-8");            System.out.println ("Customer Received" + Message + "'");        }        };    Auto reply Queue Answer--message acknowledgement mechanism in RABBITMQ Channel.basicconsume (Queue_name, true, consumer); }

We can see in the preceding code the same as the generator, followed by the acquisition of information sent by the producer, where envelope mainly store producer-related information (such as switches, routing key, etc.) body is the message entity.

2.4: Run Results

Producers:

Consumers:

Three: Achieve task distribution

Work queue

One of the advantages of a queue is that it is easy to deal with the ability to parallelize, but if we accumulate a lot of work, we need more workers to deal with, it is necessary to use the distribution mechanism.

We create a new producer NewTask

public class NewTask {    private static final String task_queue_name= "Task_queue";    public static void Main (string[] args) throws IOException, timeoutexception {        connectionfactory factory=new ConnectionFactory ();        Factory.sethost ("localhost");        Connection connection=factory.newconnection ();        Channel Channel=connection.createchannel ();   Channel.queuedeclare (task_queue_name,true,false,false,null);        Distribution information for        (int i=0;i<10;i++) {            String message= "Hello RabbitMQ" +i;            Channel.basicpublish ("", Task_queue_name,                    messageproperties.persistent_text_plain,message.getbytes ());            System.out.println ("NewTask send '" "+message+");        }        Channel.close ();        Connection.close ();    }}

Then create 2 worker Work1 and WORK2 code like

public class Work1 {private static final String Task_queue_name = "Task_queue";  public static void Main (string[] args) throws IOException, TimeoutException {final ConnectionFactory factory = new        ConnectionFactory ();        Factory.sethost ("localhost");        Connection Connection = Factory.newconnection ();        Final Channel channel = Connection.createchannel ();        Channel.queuedeclare (Task_queue_name, True, False, false, NULL);        System.out.println ("Worker1 Waiting for Messages");        The number of Channel.basicqos (1) per acquisition from the queue;  Final Consumer Consumer = new Defaultconsumer (channel) {@Override public void Handledelivery (String Consumertag, Envelope Envelope, AMQP. Basicproperties properties, byte[] body) throws IOException {String                message = new String (Body, "UTF-8"); System.out.println ("Worker1 Received ' "+ Message +" ' ");                    Try {throw new Exception ();                DoWork (message);                }catch (Exception e) {channel.abort ();                    }finally {System.out.println ("Worker1 done");                Channel.basicack (Envelope.getdeliverytag (), false);        }            }        };        Boolean autoack=false;    Message consumption complete Confirmation channel.basicconsume (task_queue_name, autoack, consumer); } private static void DoWork (String Task) {try {thread.sleep (1000);//pause 1 seconds} catch (Interr        Uptedexception _ignored) {thread.currentthread (). interrupt (); }    }}

Note: Channel.basicqos (1); guarantee to distribute only one at a time. Autoack whether the automatic reply, if true, each time the producer sends the message will be removed from the memory, then if the consumer program exits unexpectedly, then cannot obtain the data, we certainly do not want to appear such situation, so only then go to the manual reply, Whenever the consumer receives and processes the information then notifies the creator. Finally, the message is removed from the queue. If the consumer exits unexpectedly, if there are other consumers, then the message in the queue will be sent to other consumers, if not, and so on when consumers start sending again.

Reference: https://www.cnblogs.com/LipeiNet/p/5977028.html

Message Queuing RABITMQ

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.