返回顶部
首页 > 资讯 > 精选 >RabbitMQ发布确认高级问题的示例分析
  • 374
分享到

RabbitMQ发布确认高级问题的示例分析

2023-06-22 08:06:10 374人浏览 八月长安
摘要

RabbitMQ发布确认高级问题的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、发布确认高级1. 存在的问题再生产环境中由于一些不明原因导致rabb

RabbitMQ发布确认高级问题的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

1、发布确认高级

1. 存在的问题

再生产环境中由于一些不明原因导致rabbitMQ重启,在RabbitMQ重启期间生产者消息投递失败,会导致消息丢失。

1.1、发布确认SpringBoot版本

1.1.1、确认机制方案

RabbitMQ发布确认高级问题的示例分析

当消息不能正常被接收的时候,我们需要将消息存放在缓存中。

1.1.2、代码架构

RabbitMQ发布确认高级问题的示例分析

1.1.3、配置文件
spring.rabbitmq.host=192.168.123.129spring.rabbitmq.port=5672spring.rabbitmq.username=adminspring.rabbitmq.passWord=123spring.rabbitmq.publisher-confirm-type=correlated
  • NONE:禁用发布确认模式,是默认值。

  • CORRELATED:发布消息成功到交换机会触发回调方方法。

  • CORRELATED:就是发布一个就确认一个。

1.1.4、配置类
import org.springframework.amqp.core.*;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ConfirmConfig {    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";    public static final String CONFIRM_QUEUE_NAME = "confirm_queue";    public static final String CONFIRM_ROUTING_KEY = "key1";    @Bean("confirmExchange")    public DirectExchange confirmExchange(){        return new DirectExchange(CONFIRM_EXCHANGE_NAME);    }    @Bean("confirmQueue")    public Queue confirmQueue(){        return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();    }    @Bean    public Binding queueBindingExchange(@Qualifier("confirmExchange") DirectExchange confirmExchange,                                        @Qualifier("confirmQueue") Queue confirmQueue){        return BindingBuilder.bind(confirmQueue).to(confirmExchange).with(CONFIRM_ROUTING_KEY);    }}
1.1.5、回调接口
import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.rabbit.connection.CorrelationData;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Component@Slf4jpublic class MyCallBack implements RabbitTemplate.ConfirmCallback {    @Autowired    RabbitTemplate rabbitTemplate;    @PostConstruct    public void init(){        rabbitTemplate.setConfirmCallback(this);    }        @Override    public void confirm(CorrelationData correlationData, boolean b, String s) {        String id = correlationData != null ? correlationData.getId() : "";        if(b == true){            log.info("交换机已经收到id为:{}的消息",id);        }else{            log.info("交换机还未收到id为:{}消息,由于原因:{}",id,s);        }    }}
1.1.6、生产者
import com.xiao.springbootrabbitmq.utils.MyCallBack;import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.rabbit.connection.CorrelationData;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.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.PostConstruct;@RestController@RequestMapping("/confirm")@Slf4jpublic class Producer {    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";    @Autowired    RabbitTemplate rabbitTemplate;    @GetMapping("/sendMessage/{message}")    public void sendMessage(@PathVariable String message){        CorrelationData correlationData1 = new CorrelationData("1");        String routingKey1 = "key1";        rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME,routingKey1,message + routingKey1,correlationData1);        CorrelationData correlationData2 = new CorrelationData("2");        String routingKey2 = "key2";        rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME,routingKey2,message + routingKey2,correlationData2);        log.info("发送得内容是:{}",message);    }}
1.1.7、消费者
import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.core.Message;import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;@Component@Slf4jpublic class ConfirmConsumer {    public static final String CONFIRM_QUEUE_NAME = "confirm_queue";    @RabbitListener(queues = CONFIRM_QUEUE_NAME)    public void receiveMessage(Message message){        String msg = new String(message.getBody());        log.info("接收到队列" + CONFIRM_QUEUE_NAME + "消息:{}",msg);    }}
1.1.8、测试结果

1. 第一种情况

RabbitMQ发布确认高级问题的示例分析

ID1的消息正常送达,ID2的消息由于RoutingKey的错误,导致不能正常被消费,但是交换机还是正常收到了消息,所以此时由于交换机正常接收之后的原因丢失的消息不能正常被接收

2. 第二种情况

RabbitMQ发布确认高级问题的示例分析

我们再上一种情况下修改了ID1的消息的交换机的名称,所以此时回调函数会进行回答由于什么原因导致交换机无法接收成功消息

1.2、回退消息

1.2.1、Mandatory参数
  • 在仅开启了生产者确认机制的情况下,交换机接收到消息后,会直接给消息生产者发送确认消息,如果发现该消息不可路由(就是消息被交换机成功接收后,无法到达队列),那么消息会直接被丢弃,此时生产者是不知道消息被丢弃这个事件的

  • 通过设置该参数可以在消息传递过程中不可达目的地时将消息返回给生产者。

1.2.2、配置文件
spring.rabbitmq.publisher-returns=true

需要在配置文件种开启返回回调

1.2.3、生产者代码
import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.rabbit.connection.CorrelationData;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.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.PostConstruct;@RestController@RequestMapping("/confirm")@Slf4jpublic class Producer {    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";    @Autowired    RabbitTemplate rabbitTemplate;    @GetMapping("/sendMessage/{message}")    public void sendMessage(@PathVariable String message){        CorrelationData correlationData1 = new CorrelationData("1");        String routingKey1 = "key1";        rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME,routingKey1,message + routingKey1,correlationData1);        log.info("发送得内容是:{}",message + routingKey1);        CorrelationData correlationData2 = new CorrelationData("2");        String routingKey2 = "key2";        rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME,routingKey2,message + routingKey2,correlationData2);        log.info("发送得内容是:{}",message + routingKey2);    }}
1.2.4、回调接口代码
import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.core.Message;import org.springframework.amqp.core.ReturnedMessage;import org.springframework.amqp.rabbit.connection.CorrelationData;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Component@Slf4jpublic class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback {    @Autowired    RabbitTemplate rabbitTemplate;    @PostConstruct    public void init(){        rabbitTemplate.setConfirmCallback(this);        rabbitTemplate.setReturnsCallback(this);    }        @Override    public void confirm(CorrelationData correlationData, boolean b, String s) {        String id = correlationData != null ? correlationData.getId() : "";        if(b == true){            log.info("交换机已经收到id为:{}的消息",id);        }else{            log.info("交换机还未收到id为:{}消息,由于原因:{}",id,s);        }    }    @Override    public void returnedMessage(ReturnedMessage returnedMessage) {        Message message = returnedMessage.getMessage();        String exchange = returnedMessage.getExchange();        String routingKey = returnedMessage.getRoutingKey();        String replyText = returnedMessage.getReplyText();        log.error("消息{},被交换机{}退回,回退原因:{},路由Key:{}",new String(message.getBody()),exchange,replyText,routingKey);    }}
1.2.5、测试结果

其他类的代码与上一小节案例相同

RabbitMQ发布确认高级问题的示例分析

ID2的消息由于RoutingKey不可路由,但是还是被回调函数处理了。

1.3、备份交换机

1.3.1、代码架构图

RabbitMQ发布确认高级问题的示例分析

这里我们新增了备份交换机、备份队列、报警队列。它们绑定关系如图所示。如果确认交换机成功接收的消息无法路由到相应的队列,就会被确认交换机发送给备份交换机

1.3.2、配置类代码
import org.springframework.amqp.core.*;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ConfirmConfig {    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";    public static final String CONFIRM_QUEUE_NAME = "confirm_queue";    public static final String BACKUP_EXCHANGE_NAME = "backup_exchange";    public static final String BACKUP_QUEUE_NAME = "backup_queue";    public static final String WARNING_QUEUE_NAME = "warning_queue";    public static final String CONFIRM_ROUTING_KEY = "key1";    @Bean("confirmExchange")    public DirectExchange confirmExchange(){        return ExchangeBuilder.directExchange(CONFIRM_EXCHANGE_NAME).durable(true)                .withArgument("alternate-exchange",BACKUP_EXCHANGE_NAME).build();    }    @Bean("confirmQueue")    public Queue confirmQueue(){        return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();    }    @Bean("backupExchange")    public FanoutExchange backupExchange(){        return new FanoutExchange(BACKUP_EXCHANGE_NAME);    }    @Bean("backupQueue")    public Queue backupQueue(){        return QueueBuilder.durable(BACKUP_QUEUE_NAME).build();    }    @Bean("warningQueue")    public Queue warningQueue(){        return QueueBuilder.durable(WARNING_QUEUE_NAME).build();    }    @Bean    public Binding queueBindingExchange(@Qualifier("confirmExchange") DirectExchange confirmExchange,                                        @Qualifier("confirmQueue") Queue confirmQueue){        return BindingBuilder.bind(confirmQueue).to(confirmExchange).with(CONFIRM_ROUTING_KEY);    }    @Bean    public Binding queueBindingExchange1(@Qualifier("backupExchange") FanoutExchange backupExchange,                                        @Qualifier("backupQueue") Queue backupQueue){        return BindingBuilder.bind(backupQueue).to(backupExchange);    }    @Bean    public Binding queueBindingExchange2(@Qualifier("backupExchange") FanoutExchange backupExchange,                                         @Qualifier("warningQueue") Queue warningQueue){        return BindingBuilder.bind(warningQueue).to(backupExchange);    }}
1.3.3、消费者代码
import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.core.Message;import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;@Component@Slf4jpublic class WarninGConsumer {    public static final String WARNING_QUEUE_NAME = "warning_queue";    @RabbitListener(queues = WARNING_QUEUE_NAME)    public void receiveMessage(Message message){        String msg = new String(message.getBody());        log.info("报警发现不可路由的消息内容为:{}",msg);    }}
1.3.4、测试结果

RabbitMQ发布确认高级问题的示例分析

mandatory参数与备份交换机可以一起使用的时候,如果两者同时开启,备份交换机优先级高

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网精选频道,感谢您对编程网的支持。

--结束END--

本文标题: RabbitMQ发布确认高级问题的示例分析

本文链接: https://lsjlt.com/news/303444.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • RabbitMQ发布确认高级问题的示例分析
    RabbitMQ发布确认高级问题的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、发布确认高级1. 存在的问题再生产环境中由于一些不明原因导致rabb...
    99+
    2023-06-22
  • 聊聊RabbitMQ发布确认高级问题
    目录1、发布确认高级1.1、发布确认SpringBoot版本1.1.1、确认机制方案1.1.2、代码架构图1.1.3、配置文件1.1.4、配置类1.1.5、回调接口1.1.6、生产者...
    99+
    2024-04-02
  • java高并发中并发级别的示例分析
    这篇文章给大家分享的是有关java高并发中并发级别的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。阻塞一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继续执行。当我们使用synchronized...
    99+
    2023-06-25
  • 高分屏下canvas模糊问题的示例分析
    这篇文章将为大家详细讲解有关高分屏下canvas模糊问题的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言最近在做项目的时候发现,在公司电脑上没问题,在自己电脑上确有问题。做的是canvas的项...
    99+
    2023-06-09
  • PHP开发安全问题的示例分析
    PHP开发安全问题的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。对于互联网应用的开发,作为开发者必须时刻牢记安全观念,并在开发的...
    99+
    2024-04-02
  • Redis高级应用的示例分析
    小编给大家分享一下Redis高级应用的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Redis高级实用特性分6部分:1、...
    99+
    2024-04-02
  • Oracle高级队列的示例分析
    小编给大家分享一下Oracle高级队列的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Oracle高级队列(Advanc...
    99+
    2024-04-02
  • CSS高级语法的示例分析
    这篇文章主要介绍CSS高级语法的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 选择器的分组 你可以对选择器进行分组,这样,被分组的选择器就可以分享相同的声明。 用逗号...
    99+
    2024-04-02
  • mysqldump问题的示例分析
    mysqldump问题的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。导出:mysqldump数据库[表]>/t...
    99+
    2024-04-02
  • jQuery表单验证之密码确认的示例分析
    这篇文章给大家分享的是有关jQuery表单验证之密码确认的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。代码:<!DOCTYPE html> <...
    99+
    2024-04-02
  • Java面试题之分布式的示例分析
    这篇文章主要为大家展示了“Java面试题之分布式的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java面试题之分布式的示例分析”这篇文章吧。面试题1:说说什么分布式事务?解释一下什么是...
    99+
    2023-06-20
  • 分布式服务Dubbo+Zookeeper安全认证的示例分析
    这篇文章给大家分享的是有关分布式服务Dubbo+Zookeeper安全认证的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。问题Zookeeper+dubbo,如何设置安全认证?不想让其他服务连接Zooke...
    99+
    2023-05-30
    dubbo zookeeper
  • CSS高级实用技巧的示例分析
    本篇文章给大家分享的是有关CSS高级实用技巧的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。使用 :not() 在菜单上应用/取消应用...
    99+
    2024-04-02
  • PHP中ThinkPHP高级查询的示例分析
    小编给大家分享一下PHP中ThinkPHP高级查询的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!php的框架有哪些php的框架:1、Laravel,La...
    99+
    2023-06-14
  • linux中awk高级应用的示例分析
    这篇文章主要为大家展示了“linux中awk高级应用的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux中awk高级应用的示例分析”这篇文章吧。处理前的文档: Mike ...
    99+
    2023-06-09
  • webpack3升级到webpack4版本遇到问题的示例分析
    这篇文章主要介绍了webpack3升级到webpack4版本遇到问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。据说webpac...
    99+
    2024-04-02
  • WMS问题处理的示例分析
    这篇文章主要介绍了WMS问题处理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。采购订单没有生成上传订单号pkg_inpurchas...
    99+
    2024-04-02
  • Redis缓存问题的示例分析
    这篇文章给大家分享的是有关Redis缓存问题的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、Redis缓存的应用在我们的实际业务场景中,Redis 一般和其他数据库搭...
    99+
    2024-04-02
  • Node.js面试问题的示例分析
    这篇文章主要介绍了Node.js面试问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是error-first的回调方式Err...
    99+
    2024-04-02
  • Java中文问题的示例分析
    这篇文章将为大家详细讲解有关Java中文问题的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。我来说一下tomcat如何实现JSP的你就明白了。预备知识: 1.字节和unicode  Java内核是...
    99+
    2023-06-03
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作