Java for Web Learning Notes (93): Messages and Clusters (8) RABBITMQ and message mode (medium) __java

Source: Internet
Author: User
Tags ack rabbitmq
Work queues: Competitive consumption patterns (competing consumers pattern)

Simple mode can also be used for multiple client (Subsriber) to get messages, compared to simple schemas: we want the data to be really handled by the client, Client processing should send a BASIC.ACK message to the server, if the client for a reason failed to handle, when the channel shutdown, connection shutdown or interrupt, the message should be able to allocate to other client for processing. We want to get only one message (or several) at a time, instead of taking all the messages in the queue, to better load-balance. We want the unhandled message to remain in the queue after the server restarts. We will also learn to add headers for AMQP.

The published code ignores the channel and connection shutdown. See also [1]

connectionfactory factory = new ConnectionFactory (); Factory.sethost ("191.8.1.107");
Factory.setusername ("test");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel Channel = Connection.createchannel (); The "3" parameter 2:durable True if we are declaring a durable queue (the queue will survive a server restart), which meets the requirements: We hope that after the server restarts, The unhandled message is still in the queue.
It should be noted that if the declared durable (true or false) is not allowed to change, the exception is reported, that is, once the queue in the server is created, this property cannot be changed.
Channel.queuedeclare (Task_queue_name, True, False, false, NULL);
"4" Parameter 3: Add Content-type to Text/plain as AMQP header, demonstrating how to set the header for AMQP. The "3" messageproperties.persistent_text_plain indicates that messages are stored in the form of text in a disk to be persisted. Note that RABBITMQ message persistence is not very sure, so the message to write a disk, there is a certain time difference, if the accident stopped, there is no way.
If you need to be very robust to ensure that you need some way to return confirmation to the Publisher, publish batches of messages and wait for outstanding confirms. Channel.basicpublish ("", Task_queue_name, Messageproperties.persistent_text_plain, Message.getbytes ("UTF-8")); 

The

received code that ignores the shutdown of channel and connection. We use sleep for some time to simulate the time spent processing messages.

ConnectionFactory factory = new ConnectionFactory ();
Factory.sethost ("191.8.1.107");
Factory.setusername ("test");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel Channel = Connection.createchannel ();
Channel.queuedeclare (Task_queue_name, True, False, false, NULL);
"2" Maximum number of messages that's the server will deliver, 0 if unlimited, which takes only one message from the server at a time.

Channel.basicqos (1); Final Consumer Consumer = new Defaultconsumer (channel) {@Override public void Handledelivery (String consumertag, Envelope Envelope, Basicproperties Properties, byte[] body throws IOException {String mess
        Age = new String (Body, "UTF-8"); /* Small example, the following three log display * 11:11:33.903 [pool-2-thread-6] [INFO] Envelope (deliverytag=6, Redeliver=false, exchange=, R OUTINGKEY=TASK_QUEUE-1) * 11:11:33.903 [pool-2-thread-6] [INFO] #contentHeader <basic> (content-type=text/pl Ain, Content-encoding=null, Headers=null, Delivery-mode=2, Priority=0, Correlation-id=null, Reply-to=null, Expiration=null, Message-id=null, Timestamp=null, type= NULL, User-id=null, App-id=null, cluster-id=null) * 11:11:33.903 [pool-2-thread-6] [INFO] Properties-contentty
        Pe:text/plain * * Log.info ("Envelope: {}", Envelope);
        Log.info ("Properties: {}", properties);

        Log.info ("Properties-contenttype: {}", Properties.getcontenttype ());  try{Sleep (Message.length ());///simulate asynchronous processing consumes a certain amount of time}finally{log.info ("[x]
            Done ");  
        "1" replies a Basic.ack message to the server Channel.basicack (Envelope.getdeliverytag (), false);
}
    }
}; "1" Parameter 2 is false: Inform server,client after processing, reply to an ACK Channel.basicconsume (Task_queue_name, false, consumer);

We can view messages that do not receive an ACK on the admin page or through the command line rabbitmqctl list_queues name Messages_ready messages_unacknowledged

RABBITMQ server sends messages evenly to each client in a polling mechanism, even if a client has strong processing power, Quickly reply to Basic.ack, still as if still press Round-robin way, send in sequence, because the server is not wait for basic.ack, only occurs, but after receiving message, on the basis of Round-robin polling way to send, after receiving Basic.ack, will messages from The queue is deleted. If we know clearly that a client has a strong handling capacity, we can use Channel.basicqos (2), and distribute two messages to it at a time, equivalent to weight=2. publish/subscribe:sending messages to many consumers at once


In fact, instead of writing messages to the queue, producer is sent to exchange, where exchange decides to put messages into a queue, some queues, or discard the message. There are several modes of exchange:Direct, topic, headers, and fanout. The Publish/subcribe mode uses Fanout, which is broadcast to all queues bound to that exchange.

The following is the code for the sending and receiving side, and the same omission of the channel and connection shutdown. Also refer to [2]

Sending party:

ConnectionFactory factory = new ConnectionFactory ();
Factory.sethost ("191.8.1.107");
Factory.setusername ("test");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();
Channel Channel = Connection.createchannel ();    
Create an exchange with a type of fanout, named Exchange_name
//In the previous two examples, Exchange's name is set to "", that is, use the default Exchange, also known as nameless Exchange, Route the message to the same queue as the Routing_key name
channel.exchangedeclare (Exchange_name, builtinexchangetype.fanout);
Published to a specific exchange, in Fanout, the Routint_key (queue name) is ignored and we fill in "".
channel.basicpublish (Exchange_name, "", NULL, Message.getbytes ("UTF-8"));

Receiving Party:

ConnectionFactory factory = new ConnectionFactory ();
Factory.sethost ("191.8.1.107");
Factory.setusername ("test");
Factory.setpassword ("123456");
Connection Connection = Factory.newconnection ();

Channel Channel = Connection.createchannel ();
Channel.exchangedeclare (Exchange_name, builtinexchangetype.fanout); /* Temporary queues. This example shows the production of a temporary queue (a new empty queue with no old messages), the server gives a random name, and the queue is automatically deleted when the client disconnects. Channel.queuedeclare () with no parameters will satisfy this requirement. */String QueueName = Channel.queuedeclare (). Getqueue (); Name Example: AMQ.GEN-JZTY20BRGKO-HJMUJJ0WLG/* binging: Tells Exchange to send a message to a queue. In a fanout manner, Exchange sends messages to all bound queues.

* * Channel.queuebind (QueueName, Exchange_name, ""); Consumer Consumer = new Defaultconsumer (channel) {@Override public void Handledelivery (String consumertag, Envelo PE envelope, basicproperties properties, byte[] throws IOException {String message = new Strin
        G (Body, "UTF-8");
    Log.info (Tag + "[x] Received '" + Message + "'");
}
}; Channel.basicconsume (QueueName, True, consumer); 
routing:receiving Messages selectively

In the Publish/Subscribe mode further, the queue only accepts a type of message for a publication. The image above takes log exchange as an example, and different queues receive different log levels. This is the routing mode. The concrete can refer to [3].

When we focus on the Exchange Mode as direct, the queue is not only associated with Exchange, but also with specific routing_key bindings.

We learn further through code, ignoring the channel and connection closures, and ignoring the code to create connection and create channel, which is no different from the previous.

Private string[] Testroutingkey = {"Error", "info", "error", "Warning", "info"}; private void Routingsend () throws exception{...

    Create connection and Channel ... channel.exchangedeclare (Exchange_name, "direct");
        for (int i = 0; I <5 i + +) {thread.sleep (2_000l);
        String message = "message-" + i + "-" + testroutingkey[i];
        Log.info ("[X] Sent '" + Message + "'");
    Channel.basicpublish (Exchange_name, testroutingkey[i], NULL, message.getbytes ("UTF-8")); } private void Routingrecv (String...routingkeys) throws exception{... Create connection and Channel ...//exchange type is direct, which will be judged by Routing_key to which queue to send.
    The fanout of the previously learned publish subscription model is broadcast type, and as long as the exchange-bound queue is sent, the Routing_key is ignored.
    Channel.exchangedeclare (Exchange_name, "direct");
    String queuename = Channel.queuedeclare (). Getqueue (); for (String Routingkey:routingkeys) {///bind both Exchange and Routing_key,exchange will send the Routing_key message to the queue channel.q Ueuebind (QueueName, Exchange_name, Routingkey);
    Consumer Consumer = new Defaultconsumer (channel) {@Override public void Handledelivery (String Consumertag, Envelope Envelope, basicproperties Properties, byte[] body) throws Ioexcep
            tion {String message = new String (Body, "UTF-8");
        Log.info ("[X] Received '" + envelope.getroutingkey () + "': '" + Message + "', {}", properties);
    }
    };    
Channel.basicconsume (QueueName, true, consumer); }
topics:receiving messages based on a pattern (topics)

Topic mode is similar to direct mode, but it provides a fuzzy match for Routing_key. The format of the Routing_key is in the form of the a.b.c.d, where each word is used in the middle. Delimited, fuzzy matching support * and # * denotes a word #表示零或者多个词

The following code is very similar to the direct mode, and we omit the channel and connection shutdown.

Code to send:

... Slightly: Create connection and Channel ...
Channel.exchangedeclare (Topic_exchange_name, "TOPIC");
Channel.basicpublish (Topic_exchange_name, "Quick.orange.fox", NULL, Message1.getbytes ("UTF-8")); will be sent to Q1
Channel.basicpublish (topic_exchange_name, "lazy.pink.rabbit", NULL, Message2.getbytes ("UTF-8")); will be sent to Q2

Received code, taking Q2 as an example:

... Slightly: Create connection and Channel ...        
Channel.exchangedeclare (Topic_exchange_name, "TOPIC");
String queuename = Channel.queuedeclare (). Getqueue ();        
Channel.queuebind (QueueName, Topic_exchange_name, "*.*.rabbit");
Channel.queuebind (QueueName, Topic_exchange_name, "lazy.#");

Consumer Consumer = new Defaultconsumer (channel) {
    @Override public
    void Handledelivery (String consumertag, Envelope Envelope,
                               basicproperties Properties, byte[] body throws IOException {
        String message = new String (body , "UTF-8");
        Log.info (Tag + "[x] Received '" + envelope.getroutingkey () + "': '" + Message + "', {}", properties);
    }
;
Channel.basicconsume (QueueName, true, consumer);


RELATED links: My professional Java for WEB applications related articles

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.