In our previous blog post, we used direct exchange instead of fanout exchange, and this time we looked at topic exchange.
First, Topic Exchange introduction
Topic Exchange and direct Exchange are similar and are matched by routing key and binding key, but topic Exchange can set multiple standards for routing key.
A direct router is similar to an exact query in an SQL statement; The topic router is somewhat similar to a fuzzy query in an SQL statement.
Do you remember? We introduced the classification of exchange in RABBITMQ: Publish/Subscribe (Publish/subscribe):
Direct: The post is completely based on key, for example, the binding set the routing key to "ABC", then the client submits the message, only the key is set to "ABC" will be posted to the queue. Topic: Post a pattern match for key, the symbol "#" matches one or more words, the symbol " * "match exactly one word." For example, "abc.#" matches "Abc.def.ghi", "abc.*" matches only "Abc.def". fanout: No key is required, it takes broadcast mode, and when a message comes in, it is posted to all queues that are bound to the switch. Headers: We can not consider it.
The following is the official website of the work model (p for the producer, X for Exhange, the Red Q Team column, c for the consumer):
Let's analyze the model.
The message it sends is used to describe the animal. The routing key has three words: <speed>.<color>.<species> The first word describes the speed, the second describes the color, and the third describes the species.
There are three binding keys, the Q1 binding key is *.orange.* (attention to all animals with orange color); Q2 has two binding keys, namely *.*.rabbit (focus on all rabbits) and lazy.# (focus on all animals with lazy speed).
Therefore, messages that have a routing key of Quick.orange.rabbit will be sent to Q1 and Q2, and a message with a routing key of Quick.orange.fox will be sent to Q1, and a message with a route key of Lazy.brown.fox will be sent to Q2. The message route keys to Lazy.pink.rabbit will be sent to Q2, but note that it will only reach Q2 once, although it matches two binding keys. The message route keys is Quick.brown.fox is discarded because it does not match any of the binding keys.
What if someone shakes a lazy.orange.male.rabbit and sends a four-word one? Because of it and the lazy. #匹配, it is sent to Q2.
Second, code example
Now let's look at the code.
- Producers
Public classLogtopicsender {//Exchange Name Public StaticString exchange_name = "Topicexchange"; Public Static voidMain (string[] args) {ConnectionFactory factory=NewConnectionFactory (); Factory.sethost ("LocalHost"); Connection Connection=NULL; Channel Channel=NULL; Try { //1. Creating connections and ChannelsConnection =factory.newconnection (); Channel=Connection.createchannel (); //2. Declaring the topic type of exchange for a channelChannel.exchangedeclare (Exchange_name, builtinexchangetype.topic); //3. Send a message to the specified exchange, the queue is specified as empty, and exchange determines which queues to send to according to the situationString Routingkey = "Info";//String routingkey = "Log4j.error";//String routingkey = "Logback.error";//String routingkey = "Log4j.warn";String msg = "Hello rabbitmq, I am" +Routingkey; Channel.basicpublish (Exchange_name, Routingkey,NULL, Msg.getbytes ()); System.out.println ("Product Send a msg:" +msg); } Catch(IOException e) {e.printstacktrace (); } Catch(TimeoutException e) {e.printstacktrace (); } finally { //4. Close the connection if(Connection! =NULL) { Try{connection.close (); } Catch(IOException e) {e.printstacktrace (); } } } }}
- Consumers
Public classLogtopicreciver { Public Static voidMain (string[] args) {ConnectionFactory factory=NewConnectionFactory (); Factory.sethost ("LocalHost"); Connection Connection=NULL; Channel Channel=NULL; Try { //1. Creating connections and ChannelsConnection =factory.newconnection (); Channel=Connection.createchannel (); //2. Declaring the topic type of exchange for a channelChannel.exchangedeclare (Logtopicsender.exchange_name, builtinexchangetype.topic); //3. Create a queue of random namesString QueueName =Channel.queuedeclare (). Getqueue (); //4. Establishing binding relationships for Exchange and queuesString[] Bindingkeys = {"#" };//string[] Bindingkeys = {"log4j.*", "#.error"};//string[] Bindingkeys = {"*.error"};//string[] Bindingkeys = {"Log4j.warn"}; for(inti = 0; i < bindingkeys.length; i++) {channel.queuebind (QueueName, Logtopicsender.exchange_name, Bindingkeys[i]); System.out.println (* * * * * Logtopicreciver keep alive, waiting for "+Bindingkeys[i]); } //5. Generate and listen to consumers via callbacksConsumer Consumer =NewDefaultconsumer (channel) {@Override Public voidhandledelivery (String consumertag, Envelope Envelope, com.rabbitmq.client.AMQP.BasicProperties Properties,byte[] body)throwsIOException {//get the message content and then processString msg =NewString (Body, "UTF-8"); System.out.println ("*********** logtopicreciver" + "Get message: [" + msg + "]"); } }; //6. Consumer NewsChannel.basicconsume (QueueName,true, consumer); } Catch(IOException e) {e.printstacktrace (); } Catch(TimeoutException e) {e.printstacktrace (); } }}
- Start the consumer as a consumer 1
- respectively string[] Bindingkeys = {"#"}, instead string[] Bindingkeys = {"log4j.*", "#.error"};/string[] Bindingkeys = {"*.error"}; /string[] Bindingkeys = {"Log4j.warn"}; and then start as Consumer 2, consumer 3, Consumer 4
- Start 4 times producer, routing key is string routingkey = "Info", String routingkey = "Log4j.error", String routingkey = "Logback.error" ;, String routingkey = "Log4j.warn";
- Watch the console log
Producer: Product send a Msg:hello rabbitmq, I am infoproduct send a Msg:hello rabbitmq, I am log4j.errorproduct send a Msg:hello RABBITMQ, I am logback.errorproduct send a Msg:hello rabbitmq, I am log4j.warn consumer 1:Logtopicreciver keep alive, waiting for #***********logtopicreciver Get message: [Hello RABBITMQ, I am Info]***********logtopicreciver Get message: [Hello rabbitmq, I am Log4j.error]***********logtopicreciver Get message: [Hello rabbitmq, I am Logback.error]***********logtopicreciver Get message: [Hello rabbitmq, I am Log4j.warn] Consumer 2:Logtopicreciver keep alive, waiting forlog4j.* * * * * Logtopicreciver keep alive, waiting for#.error***********logtopicreciver Get message: [Hello rabbitmq, I am Log4j.error]
Logtopicreciver Get message: [Hello rabbitmq, I am Logback.error]***********logtopicreciver Get message: [Hello rabbitmq, I am Log4j.warn] Consumer 3:Logtopicreciver keep alive, waiting for*. Error***********logtopicreciver Get message: [Hello rabbitmq, I am Log4j.error]***********logtopicreciver Get message: [Hello rabbitmq, I am Logback.error] Consumer 4:Logtopicreciver keep alive, waiting forLog4j.warnLogtopicreciver Get message: [Hello rabbitmq, I am Log4j.warn]
- Watch the RABBITMQ Administration page
RABBITMQ Getting Started: Topic routers (Topic Exchange)