本实例需要两个项目:rabbitmq-provider (生产者),一个rabbitmq-consumer(消费者)。
首先先建立rabbitmq-provider项目
pom.xml配置
<dependencies>
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
</dependencies>
创建application.yml文件
server: port: 8021 spring: #给项目来个名字 application: name: rabbitmq-provider #配置rabbitMq 服务器 rabbitmq: host: 127.0.0.1 port: 5672 username: guest password: guest # connection-timeout: 60s #虚拟host 可以不设置,使用server默认host #virtual-host: admin
创建DirectRabbitConfig配置类
package com.rabbitmq.provider.config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DirectRabbitConfig { // 队列,起名:TestDirectQueue @Bean public Queue TestDirectQueue() { // durable:是否持久化,默认false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在 // exclusive:暂存队列:当前连接有效,默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。 // return new Queue("TestDirectQueue",true,true,false); // 一般设置一下队列的持久化就好,其余两个就是默认false return new Queue("TestDirectQueue",true); } // Direct交换机 起名:TestDirectExchange @Bean DirectExchange TestDirectExchange() { // return new DirectExchange("TestDirectExchange",true,true); return new DirectExchange("TestDirectExchange",true,false); } // 绑定 将队列和交换机绑定,并设置用于匹配键:TestDirectRouting @Bean Binding bindingDirect() { return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting"); } }
写一个简单的接口进行消息推送,创建SendMessageController
package com.rabbitmq.provider.controller; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; import java.util.UUID; @RestController public class SendMessageController { @Autowired RabbitTemplate rabbitTemplate; //使用RabbitTemplate,这提供了接收发送等方法 @GetMapping("/sendDirectMessage") public String sendDirectMessage(){ String messageId = String.valueOf(UUID.randomUUID()); String messageData = "test message hello!"; String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")); Map<String,Object> map = new HashMap<>(); map.put("messageId",messageId); map.put("messageData",messageData); map.put("createTime",createTime); rabbitTemplate.convertAndSend("TestDirectExchange","TestDirectRouting",map); return "ok"; } }
创建主启动类ProviderMain
package com.rabbitmq.provider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) public class ProviderMain { public static void main(String[] args) { SpringApplication.run(ProviderMain.class,args); } }
启动项目,使用postman工具调用一下这个接口。
打开浏览器,输入:http://127.0.0.1:15672
进入管理页面查看消息是否增加
至此,rabbitmq-provider (生产者)暂时结束,现在开始编写rabbitmq-consumer(消费者)
创建项目rabbitmq-consumer(消费者)
pom.xml
<dependencies> <!--rabbitmq--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> <version>2.3.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.0.RELEASE</version> </dependency> </dependencies>
创建application.yml文件
server:
port: 8022
spring:
#给项目来个名字
application:
name: rabbitmq-consumer
#配置rabbitMq 服务器
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
创建DirectRabbitConfig配置类
package com.rabbitmq.consumer.config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DirectRabbitConfig { @Bean Queue TestDirectQueue() { return new Queue("TestDirectQueue",true); } @Bean DirectExchange TestDirectExchange() { return new DirectExchange("TestDirectExchange"); } @Bean Binding bindingDirect() { return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting"); } }
创建消息接收监听类,DirectReceiver.java:
package com.rabbitmq.consumer.receiver; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import java.util.Map; @Component @RabbitListener(queues = "TestDirectQueue") //监听的队列名称 public class DirectReceiver { @RabbitHandler public void process(Map testMessage) { System.out.println("第一个DirectReceiver消费者收到消息 :" + testMessage); } }
创建主启动类ConsumerMain
package com.rabbitmq.consumer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) public class ConsumerMain { public static void main(String[] args) { SpringApplication.run(ConsumerMain.class,args); } }
运行rabbitmq-consumer项目,使用postman请求一下生产消息接口,可以看到消息被监听到并消费
设想,如果有多个监听类监听一个队列会怎么样?
在rabbitmq-consumer项目上创建监听类DirectReceiverNew
package com.rabbitmq.consumer.receiver; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import java.util.Map; @Component @RabbitListener(queues = "TestDirectQueue") public class DirectReceiverNew { @RabbitHandler public void process(Map testMessage) { System.out.println("第二个DirectReceiver消费者收到消息 :" + testMessage); } }
重启rabbitmq-consumer服务,多调用几次postman查看一下
可以看到是实现了轮询的方式对消息进行消费,而且不存在重复消费。
案例学习于这位大佬的博客:https://blog.csdn.net/qq_35387940/article/details/100514134
受益良多,记录一下笔记