• RabbitMQ------消息可靠性投递


    一。什么是消息可靠性投递?

    1.保证消息百分百发送到消息队列中去
    a.保证mq节点成功接受消息
    b.消息发送端需要接受到mq服务端接受到消息的确认应答
    
    c.完善的消息补偿机制,发送失败的消息可以再感知并二次处理

    二。RabbtiMQ消息投递路径

    1.生产者-->交换机->队列->消费者
    
    2.通过两个的点控制消息的可靠性投递
    a.生产者到交换机
      通过confirmCallback
    b.交换机到队列
      通过returnCallback
    
    3.建议
    开启消息确认机制以后,保证了消息的准确送达,但由于频繁的确认交互, rabbitmq 整体效率变低,吞吐量下降严重,不是非常重要的消息真心不建议用消息确认机制

    三。生产者到交换机

    1.通过confirmCallback实现
    
    2.生产者投递消息后,如果Broker收到消息后,会给生产者一个ACK。生产者通过ACK,可以确认这条消息是否正常发送到Broker,这种方式是消息可靠性投递的核心
    
    3.开启confirmCallback
    
    #旧版,确认消息发送成功,通过实现ConfirmCallBack接口,消息发送到交换器Exchange后触发回调
    
    spring.rabbitmq.publisher-confirms=true
    
    #新版,NONE值是禁用发布确认模式,是默认值,CORRELATED值是发布消息成功到交换器后会触发回调方法
    
    spring.rabbitmq.publisher-confirm-type: correlated

    代码:

    部分代码可参考:

    https://www.cnblogs.com/tianhengblogs/p/15341670.html

    //测试消息回调确认
        @GetMapping("/confirm")
        public String testConfirm(){
            rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
                /**
                 * @Description
                 * @param correlationData 配置
                 * @param ack 交换机是否接收到消息 true: 成功  false: 失败
                 * @param cause 失败原因
                 * @return
                 */
                @Override
                public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                    //判断
                    if (ack){
                        //更新数据库,消息状态为成功 TODO
                    }else {
                        //更新数据库,消息状态为失败 TODO
                    }
    
                    //打印信息
                    System.out.println("correlationData: " + correlationData);
                    System.out.println("ack: " + ack);
                    System.out.println("cause: " + cause);
                }
            });
            //数据库新增一条消息记录,状态为发送 TODO
    
            //发送消息
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, "order.new", "新订单消息");
            //模拟异常
            //rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME + "123", "order.new", "新订单消息");
            return "success";
        }
    View Code

    四。交换机到队列

    1.通过returnCallback
    
    2.消息从交换器发送到对应队列失败时触发
    
    3.两种模式
    
    a.交换机到队列不成功,则丢弃消息(默认)
    
    b.交换机到队列不成功,返回给消息生产者,触发returnCallback
    
    4.开启returnCallback
    
    //为true,则交换机处理消息到路由失败,则会返回给生产者
    template.setMandatory(true);
    //或者配置文件旧版本
    spring.rabbitmq.template.mandatory=true
    //新版本
    spring.rabbitmq.publisher-returns=true

    代码:

    部分代码可参考:

    https://www.cnblogs.com/tianhengblogs/p/15341670.html

    @GetMapping("return")
        public String testReturn(){
            rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
                @Override
                public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                    //打印信息
                    System.out.println("message: " + message.toString());
                }
            });
            //发送消息
    //        rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, "order.new", "新订单消息");
            //模拟异常
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, "123.order.new", "新订单消息");
            return "success";
        }
    View Code
  • 相关阅读:
    用命令行执行ROBOT FRAMEWORK
    RF ---library
    RF--- selenium
    RIDE指定log和report的输出目录
    robotframework运行时后台报错UnicodeDecodeError
    rf-demos (request)
    RobotFramework --RIDE介绍
    基于RFS(robot framework selenium)框架模拟POST/GET请求执行自动化接口测试
    volatile非原子性示例
    wait()方法写在while循环中可以在线程接到通知后再一次判断条件
  • 原文地址:https://www.cnblogs.com/tianhengblogs/p/15342226.html
Copyright © 2020-2023  润新知