spring-rabbitmq Direct reply-to 模式

前言

rabbitmq提供了request/reply模式,通过这种模式可以比较轻松的实现rpc,我们可以拿到消费者的返回,通过replytimeout设置超时时间,如果超时返回null。

一、普通request/response模式

在这里插入图片描述

  1. client将消息传递个消息服务,放入队列,消息头中包含reply_to(用于接收消息的排他队列),correlation_id(唯一的,与请求相关);
  2. server通过队列拿到消息,将消息放到名字为reply_to队列(可以是临时的,可以是持久的)
  3. 客户端从reply_to队列中拿到消息,通过correlation_id判断是哪个请求。

如果reply队列采用临时队列,消息服务会有创建队列删除队列的操作,对性能消耗比较大,特别是集群环境下,创建队列必须经过所有节点的同意。
用持久的reply队列,如果客户端不是持久的管理起来比较麻烦。

二、RabbitMQ Direct reply-to

RabbitMQ3.4.0开始支持direct reply-to,从Spring AMQP 1.4.1开始,如果没指定reply接收队列(或者接收队列名不是amq.rabbitmq.reply-to),direct reply-to是默认的使用。

简单的说就是在普通request/response模式基础上,去掉了reply队列的使用,但也不是server直接回复client,消息也经过了channel、消息服务节点。

//超时时间
rabbitTemplate.setReplyTimeout(3000);
//唯一id
rabbitTemplate.setUserCorrelationId(true);
User user=new User();
            user.setAge(1);
            user.setName("heelo");
//            CorrelationData correlationData=new CorrelationData(UUID.randomUUID().toString());
            String id=UUID.randomUUID().toString();
            System.out.println("cd:"+id);
            MessageProperties messageProperties =   new MessageProperties();
            messageProperties.setContentType("application/json");
            messageProperties.setCorrelationId(id);
            Message message=new Message(mapper.writeValueAsBytes(user),messageProperties);
//                IntStream.range(0,100).forEach(arg ->{
            Message reply =rabbitTemplate.sendAndReceive("test.exchange","directKey2", message);
            System.out.println("reply:"+reply);

AsyncRabbitTemplate

@Bean
    public AsyncRabbitTemplate  asyncRabbitTemplate (RabbitTemplate rabbitTemplate){
        return new AsyncRabbitTemplate(rabbitTemplate);
    }
User user=new User();
            user.setAge(1);
            user.setName("heelo");
            String id= UUID.randomUUID().toString();
            System.out.println("cd:"+id);
           
            MessageProperties messageProperties =   new MessageProperties();
            messageProperties.setContentType("application/json");
            messageProperties.setCorrelationId(id);
            Message message=new Message(mapper.writeValueAsBytes(user),messageProperties);
            AsyncRabbitTemplate.RabbitMessageFuture reply =asyncRabbitTemplate.sendAndReceive("test.exchange","directKey", message);
            reply.addCallback(new SuccessCallback<Message>() {
                @Override
                public void onSuccess(Message result) {
                    System.out.println("receive body:"+new String(result.getBody()));
                }
            }, new FailureCallback() {
                @Override
                public void onFailure(Throwable ex) {
                    ex.printStackTrace();
                }
            });
            //reply.get()
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 中使用 RabbitMQ 时,我们可以通过在配置文件中配置绑定关系,将交换机和队列进行绑定。具体步骤如下: 1. 在 application.properties 或 application.yml 中配置 RabbitMQ 连接信息: ``` spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 2. 创建一个交换机和一个队列,并将它们绑定在一起: ``` @Configuration public class RabbitConfig { @Bean public Queue queue() { return new Queue("myqueue", true); } @Bean public DirectExchange exchange() { return new DirectExchange("myexchange"); } @Bean public Binding binding(Queue queue, DirectExchange exchange) { return BindingBuilder.bind(queue).to(exchange).with("mykey"); } } ``` 3. 在需要发送消息的地方,注入 RabbitTemplate 并调用 convertAndSend 方法: ``` @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myexchange", "mykey", message); } ``` 4. 在需要接收消息的地方,注入 SimpleMessageListenerContainer 并实现 MessageListener 接口: ``` @Autowired private Queue queue; @Bean public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.setQueueNames(queue.getName()); container.setMessageListener(listenerAdapter); return container; } @Bean public MessageListenerAdapter listenerAdapter() { return new MessageListenerAdapter(new MyMessageListener()); } public class MyMessageListener implements MessageListener { @Override public void onMessage(Message message) { String body = new String(message.getBody()); System.out.println("Received message: " + body); } } ``` 通过以上步骤,我们就可以实现交换机和队列的绑定,以及在队列中发送和接收消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值