springboot rabbitmq reply消息直接回复模式怎么实现
导读:本文共4549字符,通常情况下阅读需要15分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要:本文小编为大家详细介绍“springboot rabbitmq reply消息直接回复模式怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“springboot rabbitmq reply消息直接回复模式怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、使用场景MQ的作用包括了解耦、异步等。通常生产者只负责生产消息,而不关心消息谁去获取,或者消费结果如何... ...
目录
(为您整理了一些要点),点击可以直达。本文小编为大家详细介绍“springboot rabbitmq reply消息直接回复模式怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“springboot rabbitmq reply消息直接回复模式怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
一、使用场景
MQ的作用包括了解耦、异步等。
通常生产者只负责生产消息,而不关心消息谁去获取,或者消费结果如何;消费者只负责接收指定的消息进行业务处理而不关心消息从哪里来一级回复业务处理情况。但我们项目中有特殊的业务存在,我们作为消息生产者在生产消息后需要接收消费者的响应结果(说白了就是类似同步调用 请求响应的MQ使用),经过研究,MQ的Reply模式(直接回复模式)就是为此种业务模式而产生。
二、Reply实战
(1)依赖与YML配置
依赖:
我这里只列出最核心的rabbitMq所需依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
配置:
无其余特殊配置,因为reply就是rabbitmq的一种交互方式而已
spring:rabbitmq:host:10.50.40.116port:5673username:adminpassword:admin
(2)RabbitMq bean配置
packagecom.leilei.demo;importorg.springframework.amqp.core.FanoutExchange;importorg.springframework.amqp.core.Queue;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/***@authorlei*@create2022-09-1921:44*@descmq配置**/@ConfigurationpublicclassRabbitMqConfig{@BeanpublicQueuebizQueue(){returnnewQueue("bizQueue");}@BeanpublicQueuereplyQueue(){returnnewQueue("replyQueue");}@BeanFanoutExchangebizExchange(){returnnewFanoutExchange("bizExchange");}}
业务类:
@Data@NoArgsConstructor@AllArgsConstructorpublicclassVehicleimplementsSerializable{privateIntegerid;privateStringname;}
(3)消息生产端
消息生产端需要做的事情:有生产消息、接受消息消费响应
(1)生产消息
1、生产消息,看业务场景选择是否生成全局唯一自定义的消息ID
2、指定消息消费后响应的队列(Reply)
/***生产消息**@param*@returnvoid*@authorlei*@date2022-09-1921:59:18*/publicvoidreplySend(){MessagePropertiesmessageProperties=newMessageProperties();messageProperties.setReplyTo("replyQueue");//todo根据业务,做一个严谨的全局唯一ID,我这里暂时用UUIDStringcorrelationId=UUID.randomUUID().toString();//我这里指定了唯一消息ID,看业务场景,消费者消费响应后,生产者端可根据消息ID做业务处理messageProperties.setCorrelationId(correlationId);Vehiclevehicle=newVehicle(1,"川A0001");Messagemessage=newMessage(JSON.toJSONString(vehicle).getBytes(),messageProperties);rabbitTemplate.convertAndSend("bizExchange","",message);System.out.println("生产者发送消息,自定义消息ID为:"+correlationId);}
(2)接受Reply响应
消费者消费消息后会将处理结果进行发送到一个队列,我们读取这里队列就可以拿到对应消息的响应结果进行业务处理了
/***接收消息响应**@parammessage*@returnvoid*@authorlei*@date2022-09-1921:59:27*/@RabbitListener(queues="replyQueue")publicvoidreplyResponse(Messagemessage){Strings=newString(message.getBody());StringcorrelationId=message.getMessageProperties().getCorrelationId();System.out.println("收到客户端响应消息ID:"+correlationId);//todo根据消息ID可判断这是哪一个消息的响应,我们就可做业务操作System.out.println("收到客户端响应消息:"+s);}
(4)消息消费端
消息消费端需要做的事有:接受消息然后进行业务处理、响应消息
(1)方法一:sendTo注解+方法返回值
一般来说,我们mq消费者监听方法不需要返回值,我们这里使用sendTo注解,则需要将要响应的消息定义为返回值,sendTo注解中指定要响应到哪个队列
重点:
1、sendTo注解指定要相应的队列(注意和生产端保持一致)
2、方法定义的返回值内容就是要响应的消息,最终会发送到sendTo注解指定要相应的队列
3、这种方法的缺点是消费端的主关性很高,因为sendTo指定的目标队列可以自己瞎写,导致生产者端无法正确收到消息响应,但我相信一般项目中也不会这么干
/***方式1SendTo指定响应队列**@parammessage*@returnString*@authorlei*@date2022-09-1916:17:52*/@RabbitListener(queues="bizQueue")@SendTo("replyQueue")publicStringhandleEmailMessage(Messagemessage){try{Stringmsg=newString(message.getBody(),StandardCharsets.UTF_8);log.info("---consumer接收到消息----{}",msg);return"客户端响应消息:"+msg+"处理完成!";}catch(Exceptione){log.error("处理业务消息失败",e);}returnnull;}
(2)方法二:读取生产端的消息使用模板发送
与普通的消费者方法一样,只需要RabbitListener注解监听业务队列;但还需要根据消息获取出ReplyTo地址,然后自己消费者方法内部手动发送消息
1、优点,更强烈的感受到消息请求 响应的交互性,流程看起来更清晰
2、缺点,代码不雅
/***方式2message消息获取内部replyrabbitmq手动发送**@parammessage*@returnString*@authorlei*@date2022-09-1916:17:52*/@RabbitListener(queues="bizQueue")publicvoidhandleEmailMessage2(Messagemessage){try{Stringmsg=newString(message.getBody(),StandardCharsets.UTF_8);log.info("---consumer接收到消息----{}",msg);StringreplyTo=message.getMessageProperties().getReplyTo();System.out.println("接收到的reply:"+replyTo);rabbitTemplate.convertAndSend(replyTo,"客户端响应消息:"+msg+"处理完成!",x->{x.getMessageProperties().setCorrelationId(message.getMessageProperties().getCorrelationId());returnx;});}catch(Exceptione){log.error("处理业务消息失败",e);}}
(3)方法三:方法返回值
这种方式与1其实是一致的,但我经过测试,因为生产者消息指定了ReplyTo的地址,消费者端无需自己再次手动指定,即生产消息到哪里,是否响应以及响应消息发送到哪里全由生产端自己空,消费者只需要处理自身业务以及返回结果
/***方式三方法有返回值,返回要响应的数据(reply由生产者发送消息时指定,消费者不做任何处理)**@parammessage*@returnString*@authorlei*@date2022-09-1923:17:47*/@RabbitListener(queues="bizQueue")publicStringhandleEmailMessage3(Messagemessage){try{Stringmsg=newString(message.getBody(),StandardCharsets.UTF_8);log.info("---consumer接收到消息----{}",msg);return"客户端响应消息:"+msg+"处理完成!";}catch(Exceptione){log.error("处理业务消息失败",e);}returnnull;}
(4)测试
生产消息:
消费消息与响应:
收到的响应:
链路:
读到这里,这篇“springboot rabbitmq reply消息直接回复模式怎么实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
springboot rabbitmq reply消息直接回复模式怎么实现的详细内容,希望对您有所帮助,信息来源于网络。