面试题:Rabbitmq怎么保证消息的可靠性?

1.消费端消息可靠性保证

消息确认(Acknowledgements):(自动(默认),手动)

消费者在接收到消息后,默认情况下RabbitMQ会自动确认消息(autoAck=true)。为保证消息可靠性,可以设置autoAck=false,使得消费者在处理完消息后手动发送确认(basicAck)。如果消费者在处理过程中发生异常或者未完成处理就终止运行,那么消息在超时时间内将不会被删除,会再次被RabbitMQ投递给其他消费者。缺点:代码冗余多,容易出现死循环。

死信队列(Dead Letter Queue)

当消息不能被正常消费时(比如达到最大重试次数),可以通过设置TTL(Time To Live)或者死信交换器(Dead Letter Exchange)将消息路由至死信队列,从而有机会后续分析和处理这些无法正常消费的消息。(人工干预)

2.生产端消息可靠性保证:

  1. 消息持久化

当生产者发布消息时,可以选择将其标记为持久化(persistent).这意味着即使 RabbitMQ 服务器重启,消息也不会丢失,因为它们会被存储在磁盘上。(默认就是这)

2.确认(Confirm)机制:(发布者确认(Publisher Confirms)

开启confirm回调模式后,RabbitMQ会在消息成功写入到磁盘并至少被一个交换器接受后,向生产者发送一个确认(acknowledgement)。若消息丢失或无法投递给任何队列,RabbitMQ将会发送一个否定确认(nack). 生产者可以根据这些确认信号判断消息是否成功送达并采取相应的重试策略。

RabbitMQ作为消息中间件并启用publisher confirms(发布者确认)publisher returns(发布者退回)机制时,可以确保消息从生产者到交换机的投递过程得到更准确的状态反馈。

发布者确认-Publisher Confirms

作用: Publisher Confirm机制允许RabbitMQ服务器通知生产者一个消息是否已经被交换机正确接收。当publisher-confirm-type设置为CORRELATED时,RabbitMQ会向生产者发送确认或否定响应,确认消息已到达交换机,但不保证消息已被路由到至少一个队列中。

2.1.配置:

spring.rabbitmq.publisher-confirm-type = CORRELATED

setConfirmCallback:

 (写到交换机,b为true.没写到交换机b为false)

 配置

spring.rabbitmq.publisher-returns = true

returnedMessage:

(这是找到交换机了,但是路由错了,没有找到对列;这在直连交换机能测出来,广播交换机没路由,只要有绑定的队列就能发送成功)

完整代码

@Service
@Slf4j
public class ConfirmProvider {@Autowiredprivate RabbitTemplate rabbitTemplate;public void send(OrderingOk msg) {rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {@Overridepublic void confirm(CorrelationData correlationData, boolean b, String s) {//没找到交换机就会falseif (b){String id = correlationData.getId();log.info("消息发送成功");}else {log.info("消息发送失败");}}});rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {@Overridepublic void returnedMessage(Message message, int i, String s, String s1, String s2) {log.info("消息发送失败");log.info("消息主体: {}", message);log.info("应答码: {}", i);log.info("描述:{}", s);log.info("消息使用的交换器 exchange : {}", s1);log.info("消息使用的路由键 routing : {}", s2);}});CorrelationData correlationData = new CorrelationData("980520");rabbitTemplate.convertAndSend("d_ex01", "erew", msg, correlationData);}
}

代码模版:

public void send(OrderingOk msg){// 设置确认回调rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {/*** 确认消息是否被交换机接收。** @param correlationData 包含消息相关数据的对象,用于识别消息的唯一性。* @param ack 表示消息是否被交换机确认接收。* @param cause 如果消息未被接收,提供未接收的原因。*/@Override //线程Bpublic void confirm(CorrelationData correlationData, boolean ack, String cause) {if(ack){//该订单状态  10 -> 20String id = correlationData.getId();// 通过这个id改订单状态} else {log.error("{]",cause);}}});// 设置退回回调, 之后投递失败的时候才会触发rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {/*** 记录被交换机退回的消息信息。** @param message 消息对象,包含消息体。* @param replyCode 返回的响应代码,用于指示退回的原因。* @param replyText 返回的响应文本,提供关于退回的详细信息。* @param exchange 退回时涉及的交换机名称。* @param routingKey 退回时使用的路由键。*/@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {System.out.println("Message was returned: " + new String(message.getBody()));System.out.println("Reply code: " + replyCode);System.out.println("Reply text: " + replyText);System.out.println("Exchange: " + exchange);System.out.println("Routing key: " + routingKey);}});//CorrelationData 创建一个关联数据,用于消息的跟踪,大部分都是业务单据的idCorrelationData correlationData = new CorrelationData("201408145676676");rabbitTemplate.convertAndSend("ordering_ok","",msg,correlationData);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/400510.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7设置静态IP地址的详细指南

CentOS 7设置静态IP地址的详细指南 配置静态IP地址是服务器或虚拟机管理的重要步骤之一,特别是在需要稳定、可预测的网络环境时。本文将详细介绍如何在CentOS 7上设置静态IP地址,帮助确保你的系统网络配置符合需求。 1. 查看当前网络配置 在进行任何更…

文件长度超出芯片容量, 超出部份将被忽略!ch341a编程器报错解决方法

出现这个错误提示,说明你正在刷的是华硕主板的cap格式BIOS文件。 编程器不支持这种文件,需要转换成编程器专用版本BIOS文件。 华硕cap格式BIOS转编程器bios文件,转换工具下载地址:https://download.csdn.net/download/baiseled/88…

再见Figma!!新的设计,代码协作神器!【送源码】

软件介绍 Penpot 是一款专门用来帮助设计师和开发者更好地合作的软件。它可以让设计师轻松地做出漂亮的设计稿,还能让这些设计稿变成真正的网站或者应用的一部分。这样,设计师和开发者之间就不会因为沟通不畅而产生麻烦了。 Penpot 专为设计师与开发者之…

在docker中进行日志切割

先在Linux中安装docker,然后在docker中安装appnode面板,并进行docker网络端口映射。接着进入docker,进行nginx日志切割。 安装docker 第一步,卸载旧版本docker。 若系统中已安装旧版本docker,则需要卸载旧版本docke…

书生大模型实战营-基础关-XTuner 微调个人小助手认知

XTuner 微调个人小助手认知 环境配置模型效果预览微调数据准备微调配置微调训练权重格式转换模型合并页面对话 环境配置 # 创建虚拟环境 conda create -n xtuner0812 python3.10 -y# 激活虚拟环境(注意:后续的所有操作都需要在这个虚拟环境中进行&#…

Docker搭建Minio容器

Docker搭建Minio容器 前言 在上一集我们介绍了分布式文件存储行业解决方案以及技术选型。最终我们决定选用Minio作为分布式文件存储。 那么这集我们就在Docker上搭建Minio容器即可。 Docker搭建Minio容器步骤 创建Minio文件目录 我们选择创建/minio/data目录 修改目录权…

40.x86游戏实战-找出XXX遍历周围的类型

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 工具下载: 链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

【C#】中IndexOf的用法

在 C# 中&#xff0c;IndexOf 方法是字符串和列表&#xff08;如 List<T>&#xff09;等数据结构中常用的方法&#xff0c;用于查找指定元素或子串首次出现的位置。以下是针对不同情况使用 IndexOf 的示例。 对于字符串 对于字符串类型&#xff0c;IndexOf 方法返回子字…

scanpy切换显示颜色总结

函数实现 import scanpy as sc adata sc.datasets.pbmc68k_reduced() print(adata) sc.pl.umap(adata,color["bulk_labels"])def change_show_color(adata,label,category_listNone,color_listNone):for i in range(len(color_list)):if(len(color_list[i])7):colo…

【人工智能】Transformers之Pipeline(九):物体检测(object-detection)

目录​​​​​​​ 一、引言 二、物体检测&#xff08;object-detection&#xff09; 2.1 概述 2.2 技术原理 2.3 应用场景 2.4 pipeline参数 2.4.1 pipeline对象实例化参数 2.4.2 pipeline对象使用参数 2.4 pipeline实战 2.5 模型排名 三、总结 一、引言 pipel…

Chromium编译指南2024 - Android篇:前置要求(一)

1.引言 欢迎阅读《Chromium编译指南2024 - Android篇》。本指南旨在帮助开发者理解和掌握在Android平台上编译Chromium的全过程。Chromium是一个开源的浏览器项目&#xff0c;由Google主导开发&#xff0c;并为多个现代浏览器提供基础代码。Android作为全球使用最广泛的移动操…

[Meachines] [Medium] Magic SQLI+文件上传+跳关TRP00F权限提升+环境变量劫持权限提升

信息收集 IP AddressOpening Ports10.10.10.185TCP:22,80 $ nmap -p- 10.10.10.185 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 06:d4:89:bf:51:…

redis面试(九)锁重入和互斥

可重入 1&#xff09;如果一开始这个锁是没有的&#xff0c;第一次来加锁&#xff0c;这段lua脚本会如何执行&#xff1f; "if (redis.call(‘exists’, KEYS[1]) 0) then " "redis.call(‘hset’, KEYS[1], ARGV[2], 1); " "redis.call(‘pexpi…

[0CTF 2016]piapiapia1

打开题目 看到登录口 字符串绕过长度限制strlen($_POST[nickname]) > 10

C语言中的结构体和位移段

在C语言中&#xff0c;结构体&#xff08;struct&#xff09;是一种用户自定义的数据类型&#xff0c;允许我们将不同类型的变量组合在一起&#xff0c;形成一个复合数据类型。结构体可以包含整型、浮点型、字符型等多种数据类型的成员。例如&#xff0c;我们可以定义一个表示人…

进程的退出函数及线程

函数wait (1)获取子进程退出状态 &#xff08;2&#xff09;回收资源销毁僵尸态子进程 #include <sys/types.h> #include <wait.h> int wait(int *status) 函数功能是&#xff1a;父进程一旦调用了wait就立即阻塞自己&#xff0c;由wait分析是否当前进程的某…

新160个crackme - 030-Acid Bytes.4

运行分析 需要破解Name和Serial PE分析 upx壳&#xff0c;32位 linux系统upx -d 脱壳 脱壳后发现是Delphi程序 静态分析&动态调试 ida搜索字符串&#xff0c;找到Your Name must be at least 6 Chars long !&#xff0c;双击进入 发现地址为红色&#xff0c;即函数未定义 选…

数据结构:顺序二叉树(堆)

目录 前言 一、堆的实现 1.1 头文件 1.2 堆的初始化及销毁 1.3 堆的插入 1.4 堆的删除 1.5 取堆顶数据和判空 前言 前面我们讲了二叉树有顺序结构和链式结构&#xff0c;今天就来讲一下顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间…

C:每日一题:二分查找

1、知识介绍&#xff1a; 1.1 概念&#xff1a; 二分查找是一种在有序数组中查找某一特定元素的搜索算法 1.2 基本思想&#xff1a; 每次将待查找的范围缩小一半&#xff0c;通过比较中间元素与目标元素的大小&#xff0c;来决定是在左半部分还是右半部分继续查找。 举个生…

servlet基础操作(get)

1&#xff0c;首先创建一个javaweb的项目 简历一般的java项目选中项目&#xff0c;双击shift出现搜索栏 找到这个框架&#xff0c;选择里面的javaweb&#xff0c;注意选择右侧版本显示为4.0的javaweb 之后部署Tomcat 我这里是本地&#xff0c;所以在本地选的是local 第一步实…