pom:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
yml:
spring: rabbitmq: host: ip port: 5672 virtual-host: / username: 账号 password: 密码
1.直连型交换机 根据消息携带的路由键将消息投递给对应队列。 流程:有一个队列绑定到一个直连交换机上,同时设置一个路由键。然后当一个消息携带着路由值X,这个消息通过生产者发送给交换机,交换机就会根据这个路由值X去寻找绑定值也是X的队列。生产者:
//直连型交换机 @Configuration public class DirectRabbitConfig { //队列 起名:TestDirectQueue @Bean public Queue TestDirectQueue() { // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效。 // exclusive:默认是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。 // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。//一般设置一下队列的持久化就好,其余两个就是默认false return new Queue("TestDirectQueue",true, false, false); } //Direct交换机 起名:TestDirectExchange @Bean DirectExchange TestDirectExchange() { return new DirectExchange("TestDirectExchange",true,false); } //绑定 将队列和交换机绑定, 并设置用于匹配键:TestDirectRouting @Bean Binding bindingDirect() { return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting4"); } }
package com.demo.business.controller; import com.demo.common.msg.BaseResponse; import com.demo.common.util.ResponseMsgUtil; 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.RequestMapping; 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 @RequestMapping("/mq") public class RabbitMQController { @Autowired RabbitTemplate rabbitTemplate; @GetMapping("/send") public BaseResponse send() { 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); //将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map); return ResponseMsgUtil.success(); } }
消费者:
package com.demo.business.controller; 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")//监听的队列名称 TestDirectQueue public class DirectReceiver { @RabbitHandler public void process(Map testMessage) { System.out.println("DirectReceiver消费者收到消息 : " + testMessage.toString()); } }
2.主题交换机 主题交换机与直连交换机流程相似,区别在于绑定键有规则(*便是一个单词,#表示零个或多个)。生产者:
package com.demo.config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class TopicRabbitConfig { //绑定键 public final static String man = "topic.man"; public final static String woman = "topic.woman"; @Bean public Queue firstQueue() { return new Queue(TopicRabbitConfig.man); } @Bean public Queue secondQueue() { return new Queue(TopicRabbitConfig.woman); } @Bean TopicExchange exchange() { return new TopicExchange("topicExchange"); } //将firstQueue和topicExchange绑定,而且绑定的键值为topic.man //这样只要是消息携带的路由键是topic.man,才会分发到该队列 @Bean Binding bindingExchangeMessage() { return BindingBuilder.bind(firstQueue()).to(exchange()).with(man); } //将secondQueue和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.# // 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列 @Bean Binding bindingExchangeMessage2() { return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#"); } }
@GetMapping("/send2") public BaseResponse send2() { 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); //将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange rabbitTemplate.convertAndSend("topicExchange", "topic.woman22222", map); return ResponseMsgUtil.success(); }
消费者:
import java.util.Map; @Component @RabbitListener(queues = "topic.woman")//队列名称 public class TopicManReceiver { @RabbitHandler public void process(Map testMessage) { System.out.println("TopicManReceiver消费者收到消息 : " + testMessage.toString()); } }
3.扇形交换机 没有路由键的概念,接收到消息后,会直接转发到绑定到它上面的所有队列。生产者:
package com.demo.config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FanoutRabbitConfig { @Bean public Queue queueA() { return new Queue("fanout.A"); } @Bean public Queue queueB() { return new Queue("fanout.B"); } @Bean public Queue queueC() { return new Queue("fanoutC"); } @Bean FanoutExchange fanoutExchange() { return new FanoutExchange("fanoutExchange"); } @Bean Binding bindingExchangeA() { return BindingBuilder.bind(queueA()).to(fanoutExchange()); } @Bean Binding bindingExchangeB() { return BindingBuilder.bind(queueB()).to(fanoutExchange()); } @Bean Binding bindingExchangeC() { return BindingBuilder.bind(queueC()).to(fanoutExchange()); } }
@GetMapping("/send3") public BaseResponse send3() { 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); //将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange rabbitTemplate.convertAndSend("fanoutExchange", null, map); return ResponseMsgUtil.success(); }
消费者:
ackage com.demo.business.controller; 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 = "fanout.A") public class FanoutReceiverA { @RabbitHandler public void process(Map testMessage) { System.out.println("FanoutReceiverA消费者收到消息 : " +testMessage.toString()); } }
package com.demo.business.controller; 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 = "fanoutC") public class FanoutReceiverC { @RabbitHandler public void process(Map testMessage) { System.out.println("FanoutReceiverC消费者收到消息 : " +testMessage.toString()); } }
另外,还有Header Exchange 头交换机、Default Exchange 默认交换机、Dead Letter Exchange 死信交换机。
4.消息回调 生产这发送消息结束后回调。yml增加配置:
spring: #确认消息已发送到交换机(Exchange) publisher-confirms: true #确认消息已发送到队列(Queue) publisher-returns: true
import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitConfig { @Bean public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){ RabbitTemplate rabbitTemplate = new RabbitTemplate(); rabbitTemplate.setConnectionFactory(connectionFactory); //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数 rabbitTemplate.setMandatory(true); rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { System.out.println("ConfirmCallback: "+"数据:"+correlationData); System.out.println("ConfirmCallback: "+"结果:"+ack); System.out.println("ConfirmCallback: "+"原因:"+cause); } }); rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { System.out.println("ReturnCallback: "+"消息:"+message); System.out.println("ReturnCallback: "+"状态码:"+replyCode); System.out.println("ReturnCallback: "+"信息:"+replyText); System.out.println("ReturnCallback: "+"交换机:"+exchange); System.out.println("ReturnCallback: "+"键值:"+routingKey); } }); return rabbitTemplate; } }
调用规则:
找不到交换机,调用:ConfirmCallback; 找到交换机,没找到队列,调用:ConfirmCallback和RetrunCallback; 交换机和队列都没找到,调用:ConfirmCallback; 消息推送成功,调用:ConfirmCallback;
5.消息确认 消费者收到消息后进行操作。 手动确认:消费者收到消息后手动调用basic.ack/basic.nack/basic.reject后,RabbitMQ收到这些消息后,才认为本次投递成功。 basicAck用于肯定确认 basicNack用于否定确认 basicReject用于否定确认,与basic.nack相比,一次只能拒绝单挑消息。
import com.elegant.rabbitmqconsumer.receiver.MyAckReceiver; import org.springframework.amqp.core.AcknowledgeMode; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MessageListenerConfig { @Autowired private CachingConnectionFactory connectionFactory; @Autowired private MyListenerConfig myListenerConfig;//消息接收处理类 @Bean public SimpleMessageListenerContainer simpleMessageListenerContainer() { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setConcurrentConsumers(1); container.setMaxConcurrentConsumers(1); container.setAcknowledgeMode(AcknowledgeMode.MANUAL);//RabbitMQ默认是自动确认,这里改为手动确认消息 container.setQueueNames("TestDirectQueue"); container.setMessageListener(myListenerConfig); return container; } }
import com.rabbitmq.client.Channel; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @Component public class MyListenerConfig implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { long deliveryTag = message.getMessageProperties().getDeliveryTag(); try { System.out.println(消息:"+message.toString()); channel.basicAck(deliveryTag, true); //channel.basicReject(deliveryTag, true);//为true会重新放回队列 } catch (Exception e) { channel.basicReject(deliveryTag, false); e.printStackTrace(); } } }
代码:https://files.cnblogs.com/files/DreamFather/mq.zip
相关推荐
该示例通过 rabbitmq_delayed_message_exchange 插件实现自定义延时时间的延时队列。 示例是纯净的,只引入了需要的架包 启动示例时,请确保MQ已经安装了延时插件(附件里带有插件及安装说明)以及示例的MQ相关的配置...
Springboot整合RabbitMQ最简单demo,适用于springcloud项目,作为消息总线适用,需要安装RabbitMQ,Mac linux可以使用命令行一键安装,在项目配置文件配置好端口即可(已默认配置),启动项目访问8080端口,参数见controller.
**SpringBoot集成RabbitMQ** Spring Boot提供了方便的RabbitMQ支持,简化了配置和操作。集成RabbitMQ需要以下步骤: 1. 添加依赖:在`pom.xml`中引入`spring-boot-starter-amqp`依赖。 2. 配置:在`application....
SpringBoot集成RabbitMQ消息中间件
springboot集成rabbitmq的简单使用,介绍了springboot集成rabbitmq的使用,利用的交换机、队列、路由key来实现的例子
SpringBoot整合RabbitMQ的详细过程 **1.该篇博文首先讲述了交换机和队列之间的绑定关系** ①direct、②fanout、③topic **2.然后讲消息的回调** 四种情况下,确认触发哪个回调函数: ①消息推送到server,但是在...
这个项目是一个基础的SpringBoot与RabbitMQ集成示例,展示了如何在Java环境中利用SpringBoot的便利性构建消息队列系统。实际应用中,你可能需要处理更复杂的情况,如多个消费者、交换机、路由键等。不过,这个简单的...
在Spring Boot应用中整合RabbitMQ,以确保消息100%投递,是一个关键的实践,特别是对于那些需要高可靠性和数据一致性的系统。RabbitMQ是一个流行的开源消息代理,它遵循Advanced Message Queuing Protocol (AMQP)...
springboot集成rabbitmq消息队列示例
文件内包含了rabbit安装的必需文件以及springboot整合rabbitmq的完整代码,代码里包含了原生的rabbitmq使用代码和整合springboot后的使用代码,还有rabbit队列的所有消息队列模式,代码简单易懂,解压打开就可以使用
本话题主要关注如何利用 SpringBoot 集成 RabbitMQ 来实现邮件通知功能,这在微服务间进行异步通信或触发业务流程时非常有用。 首先,让我们深入了解 SpringBoot。SpringBoot 是由 Pivotal 团队提供的全新框架,它...
标题中的“springboot整合rabbitMq和多数据源动态切换和跨域访问和gradle加maven和shiro安全框架和lombok自动getset生成”表明这是一个关于Spring Boot集成多个技术的项目。以下是对这些技术及其整合的详细解释: 1...
在压缩包`springBoot+rabbitmq`中,可能包含了上述代码的示例项目,你可以下载并运行它,以便更好地理解和实践这个简单的Spring Boot与RabbitMQ集成案例。通过这种方式,你可以快速上手并掌握Spring Boot中RabbitMQ...
本文将深入探讨如何在SpringBoot项目中集成RabbitMQ,通过代码示例来展示具体步骤和实现。 首先,集成RabbitMQ需要在SpringBoot的`pom.xml`文件中添加依赖。你需要引入`spring-boot-starter-amqp`依赖,这会包含...
首先,让我们了解Spring Boot如何集成RabbitMQ。在Spring Boot项目中引入`spring-boot-starter-amqp`依赖,它包含了对RabbitMQ的支持。接着,配置RabbitMQ的相关参数,如主机地址、端口、用户名和密码。在`...
本文主要介绍了使用SpringBoot集成RabbitMQ实现用户注册的示例代码,通过详细的示例代码,帮助读者学习和工作。该示例代码介绍了如何使用RabbitMQ实现用户注册功能,提供了详细的实现步骤和代码示例。 SpringBoot...
这个名为"SpringBoot-RabbitMQ生产者和消费者.7z"的压缩包包含两个关键部分:`rabbitmq-consumer`(消费者)和`rabbitmq-provider`(生产者),它们演示了如何在SpringBoot应用中集成并利用RabbitMQ进行数据交换。...
本教程将详细介绍如何使用SpringBoot集成RabbitMQ来实现一个延时队列,并探讨消息发送与消费确认机制以及消费者端的策略模式应用。 首先,SpringBoot是Java开发者广泛使用的快速开发框架,它简化了Spring的配置和...
6. **SpringBoot集成RabbitMQ** 在SpringBoot中,我们可以通过添加`spring-boot-starter-amqp`依赖来引入RabbitMQ支持。然后,使用Spring的`@RabbitListener`和`RabbitTemplate`注解来定义消费者和生产者。此外,还...