当前位置: 首页 > news >正文

24小时免费b站观看视频软件2345浏览器网页版

24小时免费b站观看视频软件,2345浏览器网页版,六盘水网站建设,怎样做免费网站建设RabbitMQ之发布确认高级 一、发布确认 SpringBoot 版本1.1 确认机制方案1.2 代码架构图1.3 配置文件1.4 添加配置类1.5 消息生产者1.6 回调接口1.7 消息消费者1.8 结果分析 二、回退消息2.1 Mandatory 参数2.2 消息生产者代码2.3 回调接口2.4 结果分析 三、备份交换机3.1 代码架…

RabbitMQ之发布确认高级

  • 一、发布确认 SpringBoot 版本
    • 1.1 确认机制方案
    • 1.2 代码架构图
    • 1.3 配置文件
    • 1.4 添加配置类
    • 1.5 消息生产者
    • 1.6 回调接口
    • 1.7 消息消费者
    • 1.8 结果分析
  • 二、回退消息
    • 2.1 Mandatory 参数
    • 2.2 消息生产者代码
    • 2.3 回调接口
    • 2.4 结果分析
  • 三、备份交换机
    • 3.1 代码架构图
    • 3.2 修改配置类
    • 3.3 报警消费者
    • 3.4 测试注意事项
    • 3.5 结果分析

  在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行 RabbitMQ 的消息可靠投递呢?特别是在这样比较极端的情况,RabbitMQ 集群不可用的时候,无法投递的消息该如何处理呢:

应 用 [xxx] 在 [08-1516:36:04] 发 生 [ 错 误 日 志 异 常 ] , alertId=[xxx] 。 由
[org.springframework.amqp.rabbit.listener.BlockingQueueConsumer:start:620] 触 发 。
应用 xxx 可能原因如下
服 务 名 为 :
异 常 为 : org.springframework.amqp.rabbit.listener.BlockingQueueConsumer:start:620,
产 生 原 因 如 下 :1.org.springframework.amqp.rabbit.listener.QueuesNotAvailableException:
Cannot prepare queue for listener. Either the queue doesn’t exist or the broker will not
allow us to use it.||Consumer received fatal=false exception on startup:

一、发布确认 SpringBoot 版本

1.1 确认机制方案


在这里插入图片描述

1.2 代码架构图


在这里插入图片描述

1.3 配置文件


在配置文件当中需要添加

spring.rabbitmq.publisher-confirm-type=correlated
  • NONE
    禁止发布确认模式,是默认值
  • CORRELATED
    发布消息成功到交换机后会触发回调方法
  • SIMPLE
    经测试有两种效果,其一效果和 CORRELATED 值一样会触发回调方法,其二在发布消息成功后使用 rabbitTemplate 调用 waitForConfirmswaitForConfirmsOrDie 方法 等待 broker 节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是 watiForConfirmsOrDie 方法如果返回 false 则会关闭 channel,则接下来无法发送消息到 broker
spring.rabbitmq.host=192.168.10.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123
spring.rabbitmq.publisher-confirm-type=correlated

1.4 添加配置类


@Configuration
public class ConfirmConfig {public static final String CONFIRM_EXCHANGE_NAME = "confirm.exchange";public static final String CONFIRM_QUEUE_NAME = "confirm.queue";//声明业务 Exchange@Bean("confirmExchange")public DirectExchange confirmExchange() {return new DirectExchange(CONFIRM_EXCHANGE_NAME);}// 声明确认队列@Bean("confirmQueue")public Queue confirmQueue() {return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();}// 声明确认队列绑定关系@Beanpublic Binding queueBinding(@Qualifier("confirmQueue") Queue queue, @Qualifier("confirmExchange") DirectExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("key1");}
}

1.5 消息生产者


@RestController
@RequestMapping("/confirm")
@Slf4j
public class Producer {public static final String CONFIRM_EXCHANGE_NAME = "confirm.exchange";@Autowiredprivate RabbitTemplate rabbitTemplate;@Autowiredprivate MyCallBack myCallBack;// 依赖注入 rabbitTemplate 之后再设置它的回调对象@PostConstructpublic void init() {rabbitTemplate.setConfirmCallback(myCallBack);}@GetMapping("sendMessage/{message}")public void sendMessage(@PathVariable String message) {//指定消息 id 为 1CorrelationData correlationData1 = new CorrelationData("1");String routingKey = "key1";rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME, routingKey, message + routingKey, correl ationData1);CorrelationData correlationData2 = new CorrelationData("2");routingKey = "key2";rabbitTemplate.convertAndSend(CONFIRM_EXCHANGE_NAME, routingKey, message + routingKey, correl ationData2);log.info("发送消息内容:{}", message);}
}

1.6 回调接口


@Component
@Slf4j
public class MyCallBack implements RabbitTemplate.ConfirmCallback {/*** 交换机不管是否收到消息的一个回调方法* CorrelationData* 消息相关数据* ack* 交换机是否收到消息*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {String id = correlationData != null ? correlationData.getId() : "";if(ack) {log.info("交换机已经收到 id 为:{}的消息", id);} else {log.info("交换机还未收到 id 为:{}消息,由于原因:{}", id, cause);}}
}

1.7 消息消费者


@Component
@Slf4j
public class ConfirmConsumer {public static final String CONFIRM_QUEUE_NAME = "confirm.queue";@RabbitListener(queues = CONFIRM_QUEUE_NAME)public void receiveMsg(Message message) {String msg = newString(message.getBody());log.info("接受到队列 confirm.queue 消息:{}", msg);}
}

1.8 结果分析


在这里插入图片描述

  可以看到,发送了两条消息,第一条消息的 RoutingKey 为“key1”,第二条消息的 RoutingKey 为“key2”,两条消息都成功被交换机接受,也收到了交换机的确认回调,但消费者只收到了一条消息,因为第二条消息的 RoutingKey 与队列的 BindingKey 不一致,也没有其他队列能接受这个消息,所以第二条消息被直接丢弃了。

  交换机发出了确认回调,但实际上队列没有收到消息。

二、回退消息

2.1 Mandatory 参数


  在仅开启了生产者确认机制的情况下,交换机接收到消息后,会直接给消息生产者发送确认消息,如果发现该消息不可路由,那么消息会被直接丢弃,此时生产者是不知道消息被丢弃这个事件的。那么如何让无法被路由的消息帮我想办法处理一下?最起码通知我一声,我好自己处理啊。通过设置 mandatory 参数可以在当消息传递过程中不可达目的地时将消息返回给生产者。

2.2 消息生产者代码


@Slf4j
@Component
public class MessageProducer implements RabbitTemplate.ConfirmCallBack,RabbitTemplate.ReturnCallback {@Autowiredprivate RabbitTemplate rabbitTemplate;//rabbitTemplate 注入之后就设置该值@PostConstructprivate void init() {rabbitTemplate.setConfirmCallback(this);/*** true:* 交换机无法将消息进行路由时,会将该消息返回给生产者* false:* 如果发现消息无法进行路由,则直接丢弃*/rabbitTemplate.setMandatory(true);//设置回退消息交给谁处理rabbitTemplate.setReturnCallback(this);}@GetMapping("sendMessage")public void sendMessage(String message) {//让消息绑定一个 id 值CorrelationData correlationData1 = new CorrelationData(UUID.randomUUID().toString());rabbitTemplate.convertAndSend("confirm.exchange", "key1", message + "key1", correlationData1);log.info("发送消息 id 为:{}内容为{}", correlationData1.getId(), message + "key1");CorrelationData correlationData2 = new CorrelationData(UUID.randomUUID().toString());rabbitTemplate.convertAndSend("confirm.exchange", "key2", message + "key2", correlationData2);log.info("发送消息 id 为:{}内容为{}", correlationData2.getId(), message + "key2");}@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {String id = correlationData != null ? correlationData.getId() : "";if(ack) {log.info("交换机收到消息确认成功, id:{}", id);} else {log.error("消息 id:{}未成功投递到交换机,原因是:{}", id, cause);}}@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {log.info("消息:{}被服务器退回,退回原因:{}, 交换机是:{}, 路由 key:{}", new String(message.getBody()), replyText, exchange, routingKey);}
}

2.3 回调接口


@Component
@Slf4j
public class MyCallBack implements
RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {/*** 交换机不管是否收到消息的一个回调方法* CorrelationData* 消息相关数据* ack* 交换机是否收到消息*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {String id = correlationData != null ? correlationData.getId() : "";if(ack) {log.info("交换机已经收到 id 为:{}的消息", id);} else {log.info("交换机还未收到 id 为:{}消息,由于原因:{}", id, cause);}}//当消息无法路由的时候的回调方法@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {log.error(" 消 息 {}, 被 交 换 机 {} 退 回 , 退 回 原 因 :{}, 路 由 key:{}", new String(message.getBody()), exchange, replyText, routingKey);}
}

2.4 结果分析


在这里插入图片描述

三、备份交换机

  有了 mandatory 参数和回退消息,我们获得了对无法投递消息的感知能力,有机会在生产者的消息无法被投递时发现并处理。但有时候,我们并不知道该如何处理这些无法路由的消息,最多打个日志,然后触发报警,再来手动处理。而通过日志来处理这些无法路由的消息是很不优雅的做法,特别是当生产者所在的服务有多台机器的时候,手动复制日志会更加麻烦而且容易出错。而且设置 mandatory 参数会增加生产者复杂性,需要添加处理这些被退回的消息的逻辑。如果既不想丢失消息,又不想增加生产者的复杂性,该怎么做呢?
  前面在设置私信队列的文章中,我们提到,可以为队列设置私信交换机来存储那些处理失败的消息,可是这些不可路由的消息根本没机会进入到队列,因此无法使用私信队列来保存消息。在 RabbitMQ 中,有一种叫做备份交换机的机制存在,可以很好的应对这个问题。什么是备份交换机呢?备份交换机可以理解为 RabbitMQ 中交换机的“备胎”,当我们为某一个交换机声明一个对应的备份交换机时,就是为它创建一个备胎,当交换机接收到一条不可路由消息时,将会把这条消息转发到备份交换机中,由备份交换机来进行转发和处理,通常备份交换机的类型为 Fanout,这样就能把素有消息都投递到与其绑定的队列中,然后我们在备份交换机下绑定一个队列,这样所有那些原交换机无法被路由的消息,就会进入这个队列中了。当然,我们还可以建立一个报警队列,用独立的消费者进行检测和报警。

3.1 代码架构图


在这里插入图片描述

3.2 修改配置类


@Configuration
public 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";// 声明确认队列@Bean("confirmQueue")public Queue confirmQueue() {return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();}//声明确认队列绑定关系@Beanpublic Binding queueBinding(@Qualifier("confirmQueue") Queue queue, @Qualifier("confirmExchange") DirectExchange exchange) {return BindingBuilder.bind(queue).to(exchange).with("key1");}//声明备份 Exchange@Bean("backupExchange")public FanoutExchange backupExchange() {return new FanoutExchange(BACKUP_EXCHANGE_NAME);}//声明确认 Exchange 交换机的备份交换机@Bean("confirmExchange")public DirectExchange confirmExchange() {ExchangeBuilder exchangeBuilder = ExchangeBuilder.directExchange(CONFIRM_EXCHANGE_NAME).durable(true)//设置该交换机的备份交换机.withArgument("alternate-exchange", BACKUP_EXCHANGE_NAME);return(DirectExchange) exchangeBuilder.build();}// 声明警告队列@Bean("warningQueue")public Queue warningQueue() {return QueueBuilder.durable(WARNING_QUEUE_NAME).build();}// 声明报警队列绑定关系@Beanpublic Binding warningBinding(@Qualifier("warningQueue") Queue queue, @Qualifier("backupExchange") FanoutExchange backupExchange) {return BindingBuilder.bind(queue).to(backupExchange);}// 声明备份队列@Bean("backQueue")public Queue backQueue() {return QueueBuilder.durable(BACKUP_QUEUE_NAME).build();}// 声明备份队列绑定关系@Beanpublic Binding backupBinding(@Qualifier("backQueue") Queue queue, @Qualifier("backupExchange") FanoutExchange backupExchange) {return BindingBuilder.bind(queue).to(backupExchange);}
}

3.3 报警消费者


@Component
@Slf4j
public class WarningConsumer {public static final String WARNING_QUEUE_NAME = "warning.queue";@RabbitListener(queues = WARNING_QUEUE_NAME)public void receiveWarningMsg(Message message) {String msg = new String(message.getBody());log.error("报警发现不可路由消息:{}", msg);}
}

3.4 测试注意事项


  重新启动项目的时候需要把原来的 cofirm.exchange 删除,因为我们修改了其绑定属性,不然报错:
在这里插入图片描述

3.5 结果分析


在这里插入图片描述
  mandatory 参数与备份交换机可以一起使用的时候,如果两者同时开启,消息究竟何去何从?谁优先级高,经过上面结果显示答案是备份交换机优先级高.

http://www.qdjiajiao.com/news/6093.html

相关文章:

  • 建立平台还是搭建平台seo综合查询国产
  • 做网站要排版吗宣传推广策略
  • 网站系统优点网络做推广广告公司
  • iis做网站的流程网络广告案例
  • 网站index.php被修改哪个公司做网站推广最好
  • 贵阳网站上门备案业务整合营销名词解释
  • 开设赌场罪建设网站免费网站建设平台
  • 甘德县公司网站建设策划营销推广方案
  • 7天精通网站建设实录网络推广公司是干嘛的
  • 网站优化 济南在线网站排名工具
  • 怎么把产品卖到国外去济南网站优化公司排名
  • 长葛哪里有做网站的时事热点新闻
  • 咨询服务类网站建设seo网站推广可以自己搞吗
  • 做led视频好的网站西地那非片能延时多久每次吃多少
  • 加速乐wordpress插件网络优化大师手机版
  • 细谈电商网站外链建设的策略济南最新消息
  • 门户网站建设制作哪里有整站优化
  • 学院网站建设规划全媒体广告代理加盟
  • 网站优化的重要性谷歌seo搜索引擎
  • .net 网站管理系统武汉seo哪家好
  • 网站方案范文如何引流推广产品
  • 无锡网站开发公司电话电子商务说白了就是干什么的
  • 网络调查问卷在哪个网站做网站seo哪家做的好
  • 怎么介绍自己做的静态网站seo优化网站的注意事项
  • 政府网站管理体系建设seo优化效果
  • 做彩票网站犯法不怎么做营销推广
  • 杭州网站设计公司哪家好长沙seo服务哪个公司好
  • 怎样免费建自己的网站免费建一个自己的网站
  • 网站分类有哪些网络推广计划书范文
  • 网站强制分享链接怎么做的中国万网域名注册服务内容