Reference: http://www.rabbitmq.com/tutorials/tutorial-three-java.html
Prerequisites
This tutorial assumes that RABBITMQ on the standard port ( 5672) on the Local host installation and run . If you use a different host, port, or certificate, the connection settings need to be adjusted.
in the previous tutorial, We have created a Task Force column. The assumption behind the work queue is that each task is delivered to only one consumer. In this section, we will do something completely different-we will deliver information to multiple consumers. This mode is called "Publish/Subscribe".
to illustrate this pattern, we will build a simple log system. It will contain two programs-the first one will emit the log messages, the second will receive and print them.
in our log system, the running copy of each receive program receives a message. So we can run a receiver and point the log to the hard disk; at the same time we will be able to run another receiver and view the logs on the screen.
Basically, the published log messages will be broadcast to all recipients.
Exchanges
In the previous section of this tutorial, we sent a message and received it from the queue. Now it's time to introduce a complete messaging model in rabbit.
Let's take a quick look at what's in the previous tutorial:
- a producer is the application of the user who sent the message.
- a queue is the buffer that stores the message.
- a consumer is the application of the user receiving the message.
The core idea of the messaging model in RABBITMQ is that the producer will never send any messages directly to the queue. In fact, producers don't even know whether messages will be sent to any queue.
Instead, producers can only send messages to Exchange (Exchange) . Switching is a very simple thing. on the one hand it receives messages from producers, on the other hand it pushes them to line up. Exchange must know how to process the received messages. Should you attach to a specific queue? should it be attached to many queues? or should it be discarded. These rules are defined by the interchange type .
There are several types of exchange available:Direct, topic, Headers and fanout . We will focus on the last fanout . Let's create a exchage of this type, named Logs:
Channel.exchangedeclare ( " logs","Fanout");
Fanout is very simple. If the word is the name, it simply broadcasts all the messages it receives to all the queues it knows. This is what our log system needs.
binding
the relationship between Exchange and queues is called binding . The code is as follows:
Channel.queuebind (QueueName, " logs",""");
List Bindings
You can list all bindings with the following command:
Rabbitmqctl list_bindings
Put the above together
The producer program that issued the log message does not differ much from the previous tutorial. the most important change is that we now want to post a message to our own definition of exchange with the name logs instead of an exchange without a name. We need to provide a routingkey when sending , but This value is ignored for fanout switching. The following is The code for the Emitlog.java program :
PackageRmq.publishsubscribe;/*** Created by Zuzhaoyue on 18/5/16.*/ImportCom.rabbitmq.client.BuiltinExchangeType;Importcom.rabbitmq.client.ConnectionFactory;Importcom.rabbitmq.client.Connection;ImportCom.rabbitmq.client.Channel; Public classEmitlog {Private Static FinalString exchange_name = "Logs"; Public Static voidMain (string[] argv)throwsException {connectionfactory Factory=NewConnectionFactory (); Factory.sethost ("LocalHost"); Connection Connection=factory.newconnection (); Channel Channel=Connection.createchannel (); //The types of exchange include: direct, topic, headers and fanout, our main concern in this example is Fanout//fanout type is to send messages to all queues//The following is the creation of an fanout type of exchange, named LogsChannel.exchangedeclare (Exchange_name, builtinexchangetype.fanout); String message=getMessage (argv); //1. In the last "Hello World" example, we used Channel.basicpublish ("", "Hello", NULL, Message.getbytes ()); //here is the default exchanges, an empty string "", in Basicpublish this method, the first parameter is the name of Exchange//2. Ready to send a message to our named ExchangeChannel.basicpublish (Exchange_name, "",NULL, Message.getbytes ("UTF-8")); System.out.println ("[x] Sent '" + Message + "'"); Channel.close (); Connection.close (); } Private StaticString getMessage (string[] strings) {if(Strings.length < 1) return"Info:hello world!"; returnJoinstrings (Strings, ""); } Private Staticstring joinstrings (string[] strings, String delimiter) {intLength =strings.length; if(length = = 0)return""; StringBuilder words=NewStringBuilder (strings[0]); for(inti = 1; i < length; i++) {words.append (delimiter). Append (Strings[i]); } returnwords.tostring (); }}
as you can see, after establishing the connection we declared Exchange. This step is necessary because you cannot publish to non-existent exchange.
if no queue is bound to the switch, these messages will be lost, but this is not a problem for the current example; If no consumer is listening, we can safely discard the message.
The following is the code for the receiver:
//Package rmq.workqueues;/*** Created by Zuzhaoyue on 18/5/16.*/Importcom.rabbitmq.client.*;Importjava.io.IOException; Public classReceivelogs {Private Static FinalString exchange_name = "Logs"; Public Static voidMain (string[] argv)throwsException {connectionfactory Factory=NewConnectionFactory (); Factory.sethost ("LocalHost"); Connection Connection=factory.newconnection (); Channel Channel=Connection.createchannel (); //in the previous example, we were sending a message to a queue, and the receiver was getting it from a queue, in which case naming the queue is important because you need producers and consumers to share this queue//But in this example, you do not need to give the queue name, first look at the requirements: the real-time reading log, you can see that the log system needs to be real-time, those old logs we do not need to see, so we must meet the following two points//1. Each time we connect RMQ we need a new empty queue, which can be named and created randomly to the queue, or the better way is to let the RMQ server randomly choose a name for us//2. When we close the connection to the RMQ, this queue is automatically deleted//Of course, this is already packaged in a good way. Haha: Channel.queuedeclare (). Getqueue () method, you can create a temporary, independent, automatically deleted and randomly named queueChannel.exchangedeclare (Exchange_name, builtinexchangetype.fanout); String QueueName=Channel.queuedeclare (). Getqueue (); System.out.println ("Queue name:" +queuename); //Now that we have an exchange, the next step is to have exchange send messages to the queue, and the relationship between Exchange and the queue is also called binding (binding)Channel.queuebind (QueueName, Exchange_name, ""); System.out.println ("[*] waiting for messages. To exit Press CTRL + C "); Consumer Consumer=NewDefaultconsumer (channel) {@Override Public voidhandledelivery (String consumertag, Envelope Envelope, AMQP. Basicproperties Properties,byte[] body)throwsIOException {String message=NewString (Body, "UTF-8"); System.out.println ("[x] Received '" + Message + "'"); } }; Channel.basicconsume (QueueName,true, consumer); }}
To demonstrate that different queues have received messages, we print out the name of the queue, and one is displayed on the screen and one is redirected to the file:
First consumer startup: Start Receivelog.java's main () method
Second consumer boot (redirected to file/data/rmqlogs.log):
Javac-cp/data/amqp-client-4.2.0.jar Receivelogs.java
Java-cp/data/amqp-client-4.2.0.jar:/data/slf4j-api-1.7.21.jar:. Receivelogs>/data/rmqlogs.log
Attention:
1. When starting with Javac and Java commands, you need to comment out the package code, or you will not be able to find or fail to load the main class error.
2. Two jar packages must be added, or you will not be reported to find the jar exception
When the boot is complete, we start the first Emotlog.java main () method, which allows you to observe what is printed on the screen:
At the same time, tail-f/data/rmqlogs.log displays as follows:
You can see that the two queue names are different, but the same message was received and the debug was successful.
Rabbitmq+java Getting Started (iii) use of exchange