RabbitMQ Publish/Subscribe

Source: Internet
Author: User
Tags rabbitmq

We will make some changes by sending a message to multiple consumers, which is called a publish/subscribe (like observer pattern).

To validate this pattern, we are ready to build a simple log system. This system contains two kinds of programs, one class of programs to start the log, another class of programs to receive and process logs.

In our log system, each of the running recipient programs receives a log. Then we realize that one receiver writes the received data to the hard disk, while the other recipient displays the received message on the screen. Essentially, the published log message is forwarded to all recipients.

1. Transponder (exchanges)

The core idea of the RABBITMQ message model is that producers never send any messages directly to the queue, and in general, producers don't even know which queues the messages should be sent to.

Instead, producers can only send messages to forwarders (Exchange). Forwarders are very simple, while receiving messages from the producer, and the other side pushes the message to the queue. The forwarder must know clearly how the message handles every message it receives. Should I append to a specified queue? Should I append to more than one queue? Or should they be discarded? These rules are defined by the type of the forwarder.

Some of the available forwarder types are listed below:

Direct

Topic

Headers

Fanout

We are now focusing on the last fanout, declaring the code for the forwarder type:

1 channel.exchangedeclare ("Logs", "fanout");

The Fanout type forwarder is particularly simple, and it broadcasts all the messages it introduces to all the queues it knows. But this is exactly what we need for the log system described above.

2. Anonymous forwarder (nameless Exchange)

As mentioned earlier, producers can send messages only to forwarders (Exchange), and we still have the ability to send and receive messages. This is because we used a default forwarder whose identifier is "". Code to send the message before:

1 channel.basicpublish ("", Queue_name,messageproperties.persistent_text_plain, Message.getbytes ());

The first parameter is the name of the forwarder, and we set it to "": if there is a routingkey (the second argument), the message is determined by Routingkey to which queue to send.

Now we can specify the forwarder to which the message is sent:

1 null, Message.getbytes ());

3. Temporary queue (temporary queues)

In the previous blog we have specified a specific name for the queue. Being able to name the queue is critical to us, and we need to designate the consumer as a queue. When we want to share a queue between producers and consumers, it is important to name the queue.
However, we do not care about the name of the queue for our log system. We want to receive all the messages, and we are only interested in the data that is currently being passed. Two things need to be done to meet our needs:
First, whenever we connect to rabbit we all need a new empty queue. To achieve this, we can create a queue with random numbers, or better yet, let the server give us a random name.
Second, once the consumer is disconnected from the rabbit, the queue that the consumer receives should be automatically deleted.
In Java we can use the Queuedeclare () method, without passing any parameters, to create a non-persistent, unique, automatically deleted queue and the queue name is randomly generated by the server.

1 String queuename = Channel.queuedeclare (). Getqueue ();

In general, this name is similar to AMQ.GEN-JZTY20BRGKO-HJMUJJ0WLG.

4. Binding (Bindings)

We have created a fanout forwarder and queue, and we now need to send the message to our queue through the binding to tell the forwarder.
Channel.queuebind (QueueName, "Logs", "") Parameter 1: queue name; parameter 2: Forwarder name

5, the complete example of the sending side:
1  Public classEmitlog2 {  3     Private Final StaticString exchange_name = "Ex_log"; 4   5      Public Static voidMain (string[] args)throwsIOException6     {  7         //Create connections and channels8ConnectionFactory factory =NewConnectionFactory (); 9Factory.sethost ("localhost"); TenConnection Connection =factory.newconnection ();  OneChannel Channel =Connection.createchannel ();  A         //declaring forwarders and types -Channel.exchangedeclare (Exchange_name, "Fanout" );  -            theString message =NewDate (). toLocaleString () + ": Log Something";  -         //send a message to the forwarder -Channel.basicpublish (Exchange_name, "",NULL, Message.getbytes ());  -    +System.out.println ("[X] Sent '" + Message + "'");  -    + Channel.close ();  A Connection.close ();  at    -     }   -    -}

Receiving end 1:

1  Public classReceivelogstosave2 {  3     Private Final StaticString exchange_name = "Ex_log"; 4   5      Public Static voidMain (string[] argv)throwsJava.io.IOException,6 java.lang.InterruptedException7     {  8         //Create connections and channels9ConnectionFactory factory =NewConnectionFactory (); TenFactory.sethost ("localhost");  OneConnection Connection =factory.newconnection ();  AChannel Channel =Connection.createchannel ();  -    -Channel.exchangedeclare (Exchange_name, "Fanout");  the         //Create a non-persistent, unique, and automatically deleted queue -String QueueName =Channel.queuedeclare (). Getqueue ();  -         //Specify a queue for forwarders, set binding -Channel.queuebind (QueueName, Exchange_name, "");  +    -SYSTEM.OUT.PRINTLN ("[*] waiting for messages. To exit Press CTRL + C ");  +    AQueueingconsumer consumer =NewQueueingconsumer (channel);  at         //specify recipient, second parameter is auto answer, no manual answer required -Channel.basicconsume (QueueName,true, consumer);  -    -          while(true)   -         {   -Queueingconsumer.delivery Delivery =Consumer.nextdelivery ();  inString message =NewString (Delivery.getbody ());  -    to print2file (message);  +         }   -    the     }   *    $     Private Static voidprint2file (String msg)Panax Notoginseng     {   -         Try   the         {   +String dir = receivelogstosave.class. getClassLoader (). GetResource (""). GetPath ();  AString LogFileName =NewSimpleDateFormat ("Yyyy-mm-dd")   the. Format (NewDate ());  +File File =NewFile (dir, logfilename+ ". txt");  -FileOutputStream fos =NewFileOutputStream (file,true);  $Fos.write (msg + "\ r \ n"). GetBytes ());  $ Fos.flush ();  - Fos.close ();  -}Catch(FileNotFoundException e) the         {   - E.printstacktrace (); Wuyi}Catch(IOException e) the         {   - E.printstacktrace ();  Wu         }   -     }   About}

Randomly creates a queue, then binds the queue to the forwarder, binds the consumer to the queue, and then writes the log file.

1  Public classReceivelogstoconsole2 {  3     Private Final StaticString exchange_name = "Ex_log"; 4   5      Public Static voidMain (string[] argv)throwsJava.io.IOException,6 java.lang.InterruptedException7     {  8         //Create connections and channels9ConnectionFactory factory =NewConnectionFactory (); TenFactory.sethost ("localhost");  OneConnection Connection =factory.newconnection ();  AChannel Channel =Connection.createchannel ();  -    -Channel.exchangedeclare (Exchange_name, "Fanout");  the         //Create a non-persistent, unique, and automatically deleted queue -String QueueName =Channel.queuedeclare (). Getqueue ();  -         //Specify a queue for forwarders, set binding -Channel.queuebind (QueueName, Exchange_name, "");  +    -SYSTEM.OUT.PRINTLN ("[*] waiting for messages. To exit Press CTRL + C ");  +    AQueueingconsumer consumer =NewQueueingconsumer (channel);  at         //specify recipient, second parameter is auto answer, no manual answer required -Channel.basicconsume (QueueName,true, consumer);  -    -          while(true)   -         {   -Queueingconsumer.delivery Delivery =Consumer.nextdelivery ();  inString message =NewString (Delivery.getbody ());  -System.out.println ("[X] Received '" + Message + "'");  to    +         }   -    the     }   *    $}

Randomly creates a queue, then binds the queue to the forwarder, binds the consumer to the queue, and then prints to the console.

Now run the two receivers and run the 3-time send side:

Output Result:

Send side:

[x] Sent ' 2014-7-10 16:04:54:log something '

[x] Sent ' 2014-7-10 16:04:58:log something '

[x] Sent ' 2014-7-10 16:05:02:log something '

Receiving end 1:

Receiving End 2:

[*] Waiting for messages. To exit Press CTRL + C
[x] Received ' 2014-7-10 16:04:54:log something '
[x] Received ' 2014-7-10 16:04:58:log something '
[x] Received ' 2014-7-10 16:05:02:log something '

This example implements the log system described at the beginning of our article, taking advantage of the type of transponder: Fanout.

Reference Document: http://blog.csdn.net/lmj623565791/article/details/37657225

RabbitMQ Publish/Subscribe

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.