RabbitMQ的交換器Exchange之direct(發布與訂閱 完全匹配)


1、交換器。用來接收生產者發送的消息並將這些消息路由給服務器中的隊列。三種常用的交換器類型,a、direct(發布與訂閱 完全匹配)。b、fanout(廣播)。c、topic(主題,規則匹配)。

2、direct(發布與訂閱 完全匹配)的使用。

由於使用的是SpringBoot項目結合Maven項目構建的。項目工程如下所示:

3、生產者模塊和消費者模塊分開的,但是pom.xml是一致的,如下所示:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
 5     https://maven.apache.org/xsd/maven-4.0.0.xsd">
 6     <modelVersion>4.0.0</modelVersion>
 7     <parent>
 8         <groupId>org.springframework.boot</groupId>
 9         <artifactId>spring-boot-starter-parent</artifactId>
10         <version>2.1.1.RELEASE</version>
11         <relativePath /> <!-- lookup parent from repository -->
12     </parent>
13     <groupId>com.bie</groupId>
14     <artifactId>rabbitmq-direct-provider</artifactId>
15     <version>0.0.1-SNAPSHOT</version>
16     <name>rabbitmq-direct-provider</name>
17     <description>Demo project for Spring Boot</description>
18 
19     <properties>
20         <java.version>1.8</java.version>
21     </properties>
22 
23     <dependencies>
24         <dependency>
25             <groupId>org.springframework.boot</groupId>
26             <artifactId>spring-boot-starter</artifactId>
27         </dependency>
28         <dependency>
29             <groupId>org.springframework.boot</groupId>
30             <artifactId>spring-boot-starter-web</artifactId>
31         </dependency>
32         <dependency>
33             <groupId>org.springframework.boot</groupId>
34             <artifactId>spring-boot-starter-test</artifactId>
35             <scope>test</scope>
36         </dependency>
37         <dependency>
38             <groupId>org.springframework.boot</groupId>
39             <artifactId>spring-boot-starter-amqp</artifactId>
40         </dependency>
41     </dependencies>
42 
43     <build>
44         <plugins>
45             <plugin>
46                 <groupId>org.springframework.boot</groupId>
47                 <artifactId>spring-boot-maven-plugin</artifactId>
48             </plugin>
49         </plugins>
50     </build>
51 
52 </project>

配置生產者的配置文件application.properties。配置如下所示:

 1 # 給當前項目起名稱.
 2 spring.application.name=rabbitmq-direct-provider
 3 
 4 # 配置端口號
 5 server.port=8081
 6 
 7 
 8 # 配置rabbitmq的參數.
 9 # rabbitmq服務器的ip地址.
10 spring.rabbitmq.host=192.168.110.133
11 # rabbitmq的端口號5672,區別於瀏覽器訪問界面的15672端口號.
12 spring.rabbitmq.port=5672
13 # rabbitmq的賬號.
14 spring.rabbitmq.username=guest
15 # rabbitmq的密碼.
16 spring.rabbitmq.password=guest
17 
18 # 設置交換器的名稱,方便修改.
19 # 生產者和消費者的交換器的名稱是一致的,這樣生產者生產的消息發送到交換器,消費者可以從這個交換器中消費.
20 rabbitmq.config.exchange=log.exchange.direct
21 
22 # 生產者生產消息的時候也要帶上路由鍵,隊列通過路由鍵綁定到交換器,交換器根據路由鍵將綁定到隊列上.
23 # 交換器根據不同的路由鍵將消息發送到不同隊列上.
24 # info的路由鍵.
25 rabbitmq.config.queue.info.routing.key=log.info.routing.key
26 
27 # error的路由鍵.
28 rabbitmq.config.queue.error.routing.key=log.error.routing.key

配置完畢,配置文件開始寫生產者生產消息代碼。

本模塊練習的是發布訂閱模式即Direct,分為兩個生產者LogInfo、LogError,生產者生產消息的時候也要帶上路由鍵,隊列通過路由鍵綁定到交換器(即交換器根據路由鍵將綁定到隊列上),交換器根據不同的路由鍵將消息發送到不同隊列上。

本項目指定了info的路由鍵error的路由鍵,然后生產者生產的消息發送到指定的交換器。交換器通過路由到綁定的隊列中去,最后消費者進行監聽隊列發生變化,觸發指定的方法進行消息的消費。

 1 package com.example.bie.provider;
 2 
 3 import org.springframework.amqp.core.AmqpTemplate;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.beans.factory.annotation.Value;
 6 import org.springframework.stereotype.Component;
 7 
 8 /**
 9  * 
10  * @author biehl
11  * 
12  *         生產者,生產消息同樣需要知道向那個交換器Exchange發送消息的.
13  * 
14  *         這里使用的交換器類型使用的是direct發布訂閱模式,
15  *         根據配置的路由routing-key來決定,將不同的消息路由到不同的隊列queue中。
16  *         不同的消息具有相同的路由鍵,就會進入相同的隊列當中去。
17  *
18  * 
19  */
20 @Component
21 public class RabbitMqLogInfoProduce {
22 
23     @Autowired
24     private AmqpTemplate rabbitmqAmqpTemplate;
25 
26     // 交換器的名稱Exchange
27     @Value(value = "${rabbitmq.config.exchange}")
28     private String exchange;
29 
30     // 路由鍵routingkey
31     @Value(value = "${rabbitmq.config.queue.info.routing.key}")
32     private String routingKey;
33 
34     /**
35      * 發送消息的方法
36      * 
37      * @param msg
38      */
39     public void producer(String msg) {
40         // 向消息隊列發送消息
41         // 參數1,交換器的名稱
42         // 參數2,路由鍵
43         // 參數3,消息
44         this.rabbitmqAmqpTemplate.convertAndSend(this.exchange, this.routingKey, msg);
45     }
46 
47 }
 1 package com.example.bie.provider;
 2 
 3 import org.springframework.amqp.core.AmqpTemplate;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.beans.factory.annotation.Value;
 6 import org.springframework.stereotype.Component;
 7 
 8 /**
 9  * 
10  * @author biehl
11  * 
12  *         生產者,生產消息同樣需要知道向那個交換器Exchange發送消息的.
13  * 
14  *         這里使用的交換器類型使用的是direct發布訂閱模式,
15  *         根據配置的路由routing-key來決定,將不同的消息路由到不同的隊列queue中。
16  *         不同的消息具有相同的路由鍵,就會進入相同的隊列當中去。
17  *
18  * 
19  */
20 @Component
21 public class RabbitMqLogErrorProduce {
22 
23     @Autowired
24     private AmqpTemplate rabbitmqAmqpTemplate;
25 
26     // 交換器的名稱Exchange
27     @Value(value = "${rabbitmq.config.exchange}")
28     private String exchange;
29 
30     // 路由鍵routingkey
31     @Value(value = "${rabbitmq.config.queue.error.routing.key}")
32     private String routingKey;
33 
34     /**
35      * 發送消息的方法
36      * 
37      * @param msg
38      */
39     public void producer(String msg) {
40         // 向消息隊列發送消息
41         // 參數1,交換器的名稱
42         // 參數2,路由鍵
43         // 參數3,消息
44         this.rabbitmqAmqpTemplate.convertAndSend(this.exchange, this.routingKey, msg);
45     }
46 }

這里使用web工程,瀏覽器訪問調用,方便測試。

 1 package com.example.bie.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Controller;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.ResponseBody;
 7 
 8 import com.example.bie.provider.RabbitMqLogErrorProduce;
 9 import com.example.bie.provider.RabbitMqLogInfoProduce;
10 
11 /**
12  * 
13  * @author biehl
14  *
15  */
16 @Controller
17 public class RabbitmqController {
18 
19     @Autowired
20     private RabbitMqLogInfoProduce rabbitMqLogInfoProduce;
21 
22     @Autowired
23     private RabbitMqLogErrorProduce rabbitMqLogErrorProduce;
24 
25     @RequestMapping(value = "/logInfo")
26     @ResponseBody
27     public String rabbitmqSendLogInfoMessage() {
28         String msg = "生產者===>生者的LogInfo消息message: ";
29         for (int i = 0; i < 100000; i++) {
30             rabbitMqLogInfoProduce.producer(msg + i);
31         }
32         return "生產===>  LogInfo消息message  ===> success!!!";
33     }
34 
35     @RequestMapping(value = "/logError")
36     @ResponseBody
37     public String rabbitmqSendLogErrorMessage() {
38         String msg = "生產者===>生者的LogError消息message: ";
39         for (int i = 0; i < 100000; i++) {
40             rabbitMqLogErrorProduce.producer(msg + i);
41         }
42         return "生產===>  LogError消息message  ===> success!!!";
43     }
44 
45 }

生產者的啟動類,如下所示:

 1 package com.example;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 
 6 @SpringBootApplication
 7 public class RabbitmqProducerApplication {
 8 
 9     public static void main(String[] args) {
10         SpringApplication.run(RabbitmqProducerApplication.class, args);
11     }
12 
13 }

4、生產者搞完以后,開始搞消費者。由於pom.xml配置文件一致,這里省略消費者的pom.xml配置文件。

 1 # 給當前項目起名稱.
 2 spring.application.name=rabbitmq-direct-consumer
 3 
 4 # 配置端口號
 5 server.port=8080
 6 
 7 # 配置rabbitmq的參數.
 8 # rabbitmq服務器的ip地址.
 9 spring.rabbitmq.host=192.168.110.133
10 # rabbitmq的端口號5672,區別於瀏覽器訪問界面的15672端口號.
11 spring.rabbitmq.port=5672
12 # rabbitmq的賬號.
13 spring.rabbitmq.username=guest
14 # rabbitmq的密碼.
15 spring.rabbitmq.password=guest
16 
17 # 設置交換器的名稱,方便修改.
18 # 路由鍵是將交換器和隊列進行綁定的,隊列通過路由鍵綁定到交換器.
19 rabbitmq.config.exchange=log.exchange.direct
20 
21 # info級別的隊列名稱.
22 rabbitmq.config.queue.info=log.info.queue
23 # info的路由鍵.
24 rabbitmq.config.queue.info.routing.key=log.info.routing.key
25 
26 # error級別的隊列名稱.
27 rabbitmq.config.queue.error=log.error.queue
28 # error的路由鍵.
29 rabbitmq.config.queue.error.routing.key=log.error.routing.key

消費者消費消息的編寫,如下所示:

 1 package com.example.bie.consumer;
 2 
 3 import org.springframework.amqp.core.ExchangeTypes;
 4 import org.springframework.amqp.rabbit.annotation.Exchange;
 5 import org.springframework.amqp.rabbit.annotation.Queue;
 6 import org.springframework.amqp.rabbit.annotation.QueueBinding;
 7 import org.springframework.amqp.rabbit.annotation.RabbitHandler;
 8 import org.springframework.amqp.rabbit.annotation.RabbitListener;
 9 import org.springframework.stereotype.Component;
10 
11 /**
12  * 
13  * @author biehl
14  * 
15  *         消息接收者
16  * 
17  *         1、@RabbitListener bindings:綁定隊列
18  * 
19  *         2、@QueueBinding
20  *         value:綁定隊列的名稱、exchange:配置交換器、key:路由鍵routing-key綁定隊列和交換器
21  * 
22  *         3、@Queue value:配置隊列名稱、autoDelete:是否是一個可刪除的臨時隊列
23  * 
24  *         4、@Exchange value:為交換器起個名稱、type:指定具體的交換器類型
25  * 
26  * 
27  */
28 @Component
29 @RabbitListener(bindings = @QueueBinding(
30 
31         value = @Queue(value = "${rabbitmq.config.queue.error}", autoDelete = "true"),
32 
33         exchange = @Exchange(value = "${rabbitmq.config.exchange}", type = ExchangeTypes.DIRECT),
34 
35         key = "${rabbitmq.config.queue.error.routing.key}"))
36 public class LogErrorConsumer {
37 
38     /**
39      * 接收消息的方法,采用消息隊列監聽機制.
40      * 
41      * @RabbitHandler意思是將注解@RabbitListener配置到類上面
42      * 
43      * @RabbitHandler是指定這個方法可以進行消息的接收並且消費.
44      * 
45      * @param msg
46      */
47     @RabbitHandler
48     public void consumer(String msg) {
49         // 打印消息
50         System.out.println("ERROR消費者===>消費<===消息message: " + msg);
51     }
52 
53 }
 1 package com.example.bie.consumer;
 2 
 3 import org.springframework.amqp.core.ExchangeTypes;
 4 import org.springframework.amqp.rabbit.annotation.Exchange;
 5 import org.springframework.amqp.rabbit.annotation.Queue;
 6 import org.springframework.amqp.rabbit.annotation.QueueBinding;
 7 import org.springframework.amqp.rabbit.annotation.RabbitHandler;
 8 import org.springframework.amqp.rabbit.annotation.RabbitListener;
 9 import org.springframework.stereotype.Component;
10 
11 /**
12  * 
13  * @author biehl
14  * 
15  *         消息接收者
16  * 
17  *         1、@RabbitListener bindings:綁定隊列
18  * 
19  *         2、@QueueBinding
20  *         value:綁定隊列的名稱、exchange:配置交換器、key:路由鍵routing-key綁定隊列和交換器
21  * 
22  *         3、@Queue value:配置隊列名稱、autoDelete:是否是一個可刪除的臨時隊列
23  * 
24  *         4、@Exchange value:為交換器起個名稱、type:指定具體的交換器類型
25  * 
26  * 
27  */
28 @Component
29 @RabbitListener(bindings = @QueueBinding(
30 
31         value = @Queue(value = "${rabbitmq.config.queue.info}", autoDelete = "true"),
32 
33         exchange = @Exchange(value = "${rabbitmq.config.exchange}", type = ExchangeTypes.DIRECT),
34 
35         key = "${rabbitmq.config.queue.info.routing.key}"))
36 public class LogInfoConsumer {
37 
38     /**
39      * 接收消息的方法,采用消息隊列監聽機制.
40      * 
41      * @RabbitHandler意思是將注解@RabbitListener配置到類上面
42      * 
43      * @RabbitHandler是指定這個方法可以進行消息的接收並且消費.
44      * 
45      * @param msg
46      */
47     @RabbitHandler
48     public void consumer(String msg) {
49         // 打印消息
50         System.out.println("INFO消費者===>消費: " + msg);
51     }
52 
53 }

消費者啟動主類如下所示:

 1 package com.example;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 
 6 @SpringBootApplication
 7 public class RabbitmqConsumerApplication {
 8 
 9     public static void main(String[] args) {
10         SpringApplication.run(RabbitmqConsumerApplication.class, args);
11     }
12 
13 }

5、發布訂閱模式,生產者生產消息,消費者消費消息,運行效果如下所示:

首先啟動你消費者消費消息的啟動類,再啟動你的生產者生產消息的啟動類。

 

作者:別先生

博客園:https://www.cnblogs.com/biehongli/

如果您想及時得到個人撰寫文章以及著作的消息推送,可以掃描上方二維碼,關注個人公眾號哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM