RabbitMQ应用问题大全(精心整理版)
前言
其实这部分知识我是整理在语雀上了,这里是直接复制粘贴过来的。不是很好阅读,可以直接点下方链接去语雀看,那个看的会舒服很多。
https://www.yuque.com/g/ngioig/upbg6b/fkarhyo8fpgrtyq8/collaborator/join?token=GvlO0di8KaIfO8aF&source=doc_collaborator# 《RabbitMQ常见问题知识库》
1.MQ的作⽤及应⽤场景
知识点
消息队列(MQ)是⼀种应⽤程序间的通信⽅法,它允许系统组件以异步的⽅式进⾏交互, 在不同的应⽤场景下可以展现不同的作⽤, 常⻅的应⽤场景如下:
异步解耦: 在业务流程中, ⼀些操作可能⾮常耗时, 但并不需要即时返回结果. 可以借助MQ把这些操作异步化, ⽐如 ⽤⼾注册后发送注册短信或邮件通知, 可以作为异步任务处理, ⽽不必等待这些操作完成后才告知⽤⼾注册成功.
流量削峰: 在访问量剧增的情况下, 应⽤仍然需要继续发挥作⽤, 但是是这样的突发流量并不常⻅. 如果以能处理这类峰值为标准⽽投⼊资源,⽆疑是巨⼤的浪费. 使⽤MQ能够使关键组件⽀撑突发访问压⼒, 不会因为突发流量⽽崩溃. ⽐如秒杀或者促销活动, 可以使⽤MQ来控制流量, 将请求排队, 然后系统根据⾃⼰的处理能⼒逐步处理这些请求.
异步通信: 在很多时候应⽤不需要⽴即处理消息, MQ提供了异步处理机制, 允许应⽤把⼀些消息放⼊MQ中, 但并不⽴即处理它,在需要的时候再慢慢处理.
消息分发: 当多个系统需要对同⼀数据做出响应时, 可以使⽤MQ进⾏消息分发. ⽐如⽀付成功后, ⽀付系统可以向MQ发送消息, 其他系统订阅该消息, ⽽⽆需轮询数据库.
延迟通知: 在需要在特定时间后发送通知的场景中, 可以使⽤MQ的延迟消息功能, ⽐如在电⼦商务平台中,如果⽤⼾下单后⼀定时间内未⽀付,可以使⽤延迟队列在超时后⾃动取消订单
类似问题:
1.项⽬什么场景下使⽤到了MQ, 为什么需要MQ ?
- 系统解耦
- 场景:多个系统之间需要通信,但不想直接耦合(如电商平台的订单系统、库存系统、支付系统)。
- 原因:通过 MQ,生产者(如订单系统)只需发送消息到队列,消费者(如库存系统)独立处理,互不影响。例如,订单生成后发送消息到 MQ,库存系统监听扣减库存,后续新增优惠券系统时无需修改订单系统代码。
- 异步处理
- 场景:用户注册后需发送短信、邮件等耗时操作。
- 原因:将消息发送到 MQ 后立即返回响应,消费者异步处理任务,提升系统吞吐量。例如,用户点击注册后,系统只需将消息写入 MQ,无需等待短信和邮件发送完成。
- 削峰填谷
- 场景:秒杀活动、突发流量(如春节抢红包)。
- 原因:高并发请求先存入 MQ,消费者按自身能力处理,避免数据库或服务被瞬间压垮。例如,10 万并发请求进入 MQ,消费者每秒处理 1 万,10 秒完成,避免直接冲击数据库
自己想的: 在消息分发和判题的的时候用到的MQ,系统给所有用户进行消息分发.多个判题避免线程竞争
2.RabbitMQ 的作⽤?使⽤场景有哪些 消息队列的应⽤场景
RabbitMQ 是一款功能强大的开源 MQ,核心功能包括:
- 可靠消息传递:支持持久化、确认机制,确保消息不丢失。
- 灵活路由:通过 Exchange 和 Queue 实现不同消息路由策略(如 Fanout、Direct、Topic)。
- 多语言支持:适配 Java、Python、Go 等主流语言。
主要应用场景:
- 异步任务处理:如用户注册后的短信 / 邮件发送、订单生成后的物流通知。
- 系统解耦:微服务架构中各服务通过 MQ 通信,降低依赖。
- 流量削峰:应对突发流量(如电商大促),平滑请求压力。
- 日志聚合:多个服务将日志发送到 MQ,统一处理存储或分析。
- 事件驱动架构:如订单状态变更触发库存更新、积分发放等连锁反应。
异步解耦,异步通信,流量削峰,消息分发,延迟队列
3.消息队列解耦应⽤程序的例⼦
场景:电商下单流程
- 用户下单后,订单系统将消息(如
order_created
)发送到 MQ。- 库存系统监听该消息,扣减库存。
- 支付系统监听消息,触发支付流程。
- 物流系统监听消息,准备发货。
优势:若后续新增优惠券系统,只需新增一个消费者监听order_created
消息,无需修改订单系统代码。
用户注册完后,发送注册通知或者短信,不需要同时发完
4.为什么说消息队列可以削峰
四、削峰原理
当大量请求(如 10 万 / 秒)涌入时,直接处理可能导致系统崩溃。MQ 作为中间层:
- 暂存请求:将请求存入队列,消费者按能力处理(如 1 万 / 秒)。
- 平滑流量:避免瞬间压力过大,保障系统稳定性。
类比:高速公路收费站,车多时先进入匝道排队(MQ),再逐个通过(消费者处理)。
限制流量,放在队列中一个个来,避免一次性接收多个请求导致服务器崩溃
2.了解过哪些MQ,以及他们的区别
知识点
⽬前业界有很多的MQ产品, 例如RabbitMQ, RocketMQ, ActiveMQ, Kafka, ZeroMQ等,
简单介绍其中3种:
1. Kafaka
Kafka⼀开始的⽬的就是⽤于⽇志收集和传输,追求⾼吞吐量, 性能卓越, 单机吞吐达到百万级, 在⽇志领域⽐较成熟, 功能较为简单, 主要⽀持简单的 MQ 功能. 适合⼤数据处理, ⽇志聚合, 实时分析等场景
2. RabbitMQ
采⽤Erlang语⾔开发, MQ 功能⽐较完备, 且⼏乎⽀持所有主流语⾔, 开源提供的界⾯也⾮常友好, 性能较 好, 吞吐量能达到万级, 社区活跃度较⾼,⽂档更新频繁, ⽐较适合中⼩型公司, 数据量没那么⼤, 且并发没那么⾼的场景.
3. RocketMQ 采⽤Java语⾔开发, 由阿⾥巴巴开源, 后捐赠给了Apache. 在可⽤性, 可靠性以及稳定性等⽅⾯都⾮常出 ⾊, 吞吐量能达到⼗万级, 在Alibaba集团内部⼴泛使⽤, 但⽀持的客⼾端语⾔不多, 产品较新⽂档较少, 且社区活跃度⼀般. 适合于⼤规模分布式系统, 可靠性要求⾼, 且并发⼤的场景, ⽐如互联⽹⾦融. 这些消息队列, 各有侧重, 没有好坏, 只有适合不适合, 在实际选型时, 需要结合⾃⾝需求以及MQ产品特 征, 综合考虑
了解过哪些MQ, 与其他同类产品的对⽐
kafka 和 RabbitMQ 和 RocketMQ的对⽐
一、主流 MQ 对比表格
特性 | RabbitMQ | Kafka | RocketMQ |
可靠性 | 高(持久化 + ACK) | 高(多副本) | 高(异步刷盘 + 同步复制) |
吞吐量 | 万级 TPS | 百万级 TPS | 十万级 TPS |
延迟 | 低(ms 级) | 低(ms 级) | 低(ms 级) |
消息顺序性 | 严格保证 | 分区内有序 | 严格保证 |
分布式事务 | 不支持 | 不支持 | 支持(半消息) |
复杂度 | 高(Erlang 依赖) | 中等(需理解分区) | 中等(Java 生态友好) |
生态与社区 | 成熟,多语言支持 | 丰富(与 Spark/Flink 集成) | 阿里系,Java 生态 |
kafka追求日志收集和传输,追求性能卓越,吞吐量到达10w级,支持简单的MQ功能,适合大数据处理,日志聚合,实时分析场景.
RabbitMQ采用Erlang语言开发,几乎支持所有主流语言,吞吐量到达万级,MQ功能完备,社区活跃度比较高.比较适合中小型,并发量没那么高,数据量没那么大的公司.
对⽐其他消息队列,不同mq分别⽤在什么场景
- RabbitMQ:可靠性与灵活性兼顾,适合金融、小规模高可靠场景。
- Kafka:吞吐量王者,适合日志、流计算等海量数据场景。
- RocketMQ:分布式事务与高并发平衡,适合电商核心链路。
- 其他:根据场景选择轻量级(ZeroMQ)、云原生(Pulsar)或遗留系统(ActiveMQ)。
场景 | 推荐 MQ | 原因 |
高可靠性交易 | RabbitMQ/RocketMQ | 支持消息持久化、ACK 机制,RocketMQ 还支持分布式事务 |
海量日志 / 流数据 | Kafka | 百万级 TPS 吞吐量,与大数据框架集成成熟 |
高并发电商核心链路 | RocketMQ | 支持分布式事务、严格消息顺序,吞吐量十万级 |
低延迟通信 | ZeroMQ | 内存型无中间节点,μs 级延迟 |
遗留 Java 系统 | ActiveMQ | 传统 Java 生态支持,但性能一般 |
云原生场景 | Pulsar | 多租户、持久化、流处理一体化 |
kafka 日志领域,日志收集传输聚合,大数据处理
RabbitMQ 轻量级应用开发,异步解耦通信,可靠性没那么高,数据量没那么大
RocketMQ 用在高可靠性高稳定性以及高并发大量数据的场景,比如互联网金融.
消息队列除了使⽤RabbitMQ,可以⽤RocketMQ吗?
可以,尤其适合:
- 高并发场景(如秒杀、大促);
- 消息顺序性要求严格(如物流状态更新)。
- 需要分布式事务(如订单支付与库存同步);
- 注意:RocketMQ 的部署复杂度高于 RabbitMQ,需结合团队技术栈评估。
可以的,Rocket也支持了MQ的完备功能
3.RabbitMQ的核⼼概念及⼯作流程
RabbitMQ 的核心流程
1. 生产者发送消息
- 创建消息:生产者应用程序根据业务需求创建消息内容,消息可以是文本、JSON 数据、二进制数据等,同时会为消息指定一些属性,如消息的优先级、过期时间等。
- 连接到 Broker:生产者需要与 RabbitMQ 的 Broker(服务器实例)建立 TCP 连接,之后在该连接上创建一个或多个信道(Channel),信道是进行消息通信的逻辑通道,使用信道而不是直接使用 TCP 连接可以减少系统开销。
- 指定交换机和路由键:生产者将消息发送到指定的交换机,并为消息指定路由键(routing key)。路由键是一个字符串,用于交换机根据其类型和绑定规则来决定如何将消息路由到队列。
2. 交换机路由消息
- 接收消息:交换机接收到生产者发送的消息。
- 匹配绑定规则:交换机根据自身的类型(如直连交换机、扇形交换机、主题交换机、头交换机)和绑定规则,结合消息的路由键,决定将消息路由到哪些队列。例如,直连交换机根据路由键和绑定键的精确匹配来路由消息;扇形交换机则将消息广播到所有与之绑定的队列。
- 转发消息:交换机将消息转发到匹配的队列中。
3. 队列存储消息
- 接收消息:队列接收到交换机转发过来的消息,并将其存储在队列中。
- 持久化处理(可选):如果队列设置为持久化(durable),消息会被存储在磁盘上,以防止 Broker 重启时消息丢失。
4. 消费者接收消息
- 连接到 Broker:消费者同样需要与 RabbitMQ 的 Broker 建立 TCP 连接,并创建信道。
- 订阅队列:消费者向 Broker 表明自己要监听的队列,通过信道订阅该队列。
- 接收消息:当队列中有新消息时,Broker 会将消息推送给订阅该队列的消费者(推模式),或者消费者主动从队列中拉取消息(拉模式)。
- 消息确认:消费者接收到消息并处理完成后,会向 Broker 发送确认信息(ACK),告知 Broker 该消息已成功处理,Broker 收到确认后会将消息从队列中删除。如果消费者在处理消息过程中出现异常,没有发送确认信息,Broker 会认为消息处理失败,可能会将消息重新发送给其他消费者或进行其他处理。
讲讲RabbitMQ的结构
RabbitMQ 的结构可以从逻辑结构和物理结构两个层面来理解。
逻辑结构组件
- 生产者(Producer):负责创建并发送消息到 RabbitMQ 的应用程序。例如,在一个电商系统中,订单服务在用户下单后会作为生产者将订单消息发送到 RabbitMQ。
- 消费者(Consumer):从 RabbitMQ 接收消息并进行处理的应用程序。如库存服务会作为消费者监听与订单相关的队列,当接收到订单消息后进行库存扣减操作。
- 交换机(Exchange):是消息的接收和路由中心,根据不同的类型和绑定规则将消息路由到队列。常见的交换机类型有直连交换机、扇形交换机、主题交换机和头交换机。
- 队列(Queue):用于存储消息的缓冲区,是消息的最终目的地。队列可以设置多种属性,如持久化、排他性、自动删除等。
- 绑定(Binding):建立交换机和队列之间的关联关系,通过绑定键来实现。它决定了交换机如何将消息路由到队列。
物理结构组件
- 虚拟主机(Virtual Host):是一个逻辑分组概念,为不同的用户或应用程序提供独立的环境。每个虚拟主机都有自己独立的交换机、队列和绑定,相互隔离,提高了系统的安全性和可管理性。
- Broker:RabbitMQ 服务器的实例,是整个消息队列系统的核心。它负责管理交换机、队列、绑定等组件,处理消息的收发和存储,同时提供监控、管理等功能。一个 Broker 可以包含多个虚拟主机。
4.RabbitMQ如何保证消息的可靠性
RabbitMQ消息丢失原因及其解决⽅案
消息丢失阶段 | 原因 | 解决方案 |
生产者发送消息时 | 网络问题、Broker 故障等导致消息未成功发送到 Broker | 1. 事务机制:生产者开启事务,若消息发送失败,事务回滚并重试。但这种方式会严重影响性能,因为它是同步阻塞的。例如在 Java 中使用 开启事务, 提交事务, 回滚事务。 |
消息在交换机中无法路由到指定队列 | 可能原因是代码或者配置层面错误,导致消息路由失败, | 解决办法是参考 |
Broker 存储消息时 | 磁盘故障、Broker 崩溃等导致消息丢失 | 1. 队列和消息持久化:声明队列时设置 |
消费者消费消息时 | 消费者处理消息过程中出现异常、网络中断等导致消息未正确处理 | 1. 手动确认机制(Manual Acknowledgment):消费者在处理完消息后,手动发送 ACK 给 Broker,告知 Broker 消息已成功处理。若消费者未发送 ACK 就断开连接,Broker 会将消息重新分配给其他消费者。 |
如何保证消息不丢失
要保证消息不丢失,需要从生产者、Broker 和消费者三个方面进行综合处理:
- 生产者端:采用确认机制或者事务,确保消息成功发送到 Broker。
- Broker 端:使用队列和消息持久化,以及镜像队列等方式,保证消息在 Broker 存储期间的可靠性。
- 消费者端:使用手动确认机制,只有在消息处理成功后才发送 ACK。死信队列(Dead Letter Queue,DLQ):当消息消费失败多次后,可以将消息发送到死信队列,后续进行人工处理或重试。
消息写⼊失败怎么办
- 重试机制:如果生产者发现消息写入失败(如未收到 Broker 的确认信息),可以进行重试。为了避免无限重试,可以设置最大重试次数和重试间隔时间。
- 记录日志:将写入失败的消息记录到日志中,方便后续排查问题。
- 补偿机制:对于一些重要的消息,放到死信队列通过其他方式(如人工干预)进行补偿。
消息消费失败如何处理
- 重试机制:消费者在处理消息失败时,可以进行重试。可以设置重试次数和重试间隔时间,避免无限重试。
- 死信队列:当消息重试多次仍然失败时,将消息发送到死信队列,后续进行人工处理或分析失败原因。
- 记录日志:记录消费失败的消息和错误信息,方便后续排查问题。
MQ的主动ack和被动ack有什么区别
- 主动 ack(手动确认):消费者在处理完消息后,手动调用
basicAck
方法向 Broker 发送确认信息。这种方式可以确保消息在消费者真正处理完成后才被标记为已消费,提高了消息处理的可靠性。但需要开发者自己处理确认逻辑,增加了代码复杂度。 - 被动 ack(自动确认):消费者在接收到消息后,Broker 会自动认为消息已被消费,无需消费者手动发送确认信息。这种方式简单方便,但存在一定的风险,例如消费者在处理消息过程中出现异常,消息可能会丢失。
RabbitMQ如何解决数据丢失问题, 如何保证⼀致性
- 解决数据丢失问题:通过上述提到的生产者确认机制、Broker 持久化和镜像队列、消费者手动确认机制等方式,确保消息在整个生命周期内不丢失。
- 保证一致性:
-
- 最终一致性:允许系统在一段时间内存在数据不一致的情况,但最终会达到一致。例如,在分布式系统中,通过消息队列进行异步通信,各个服务可能在不同的时间点处理消息,但最终会达成一致的状态。
- 分布式事务:结合 RabbitMQ 和分布式事务框架(如 Seata),确保在消息发送和业务处理过程中的一致性。例如,在电商系统中,订单服务发送消息到 RabbitMQ 通知库存服务扣减库存,同时使用分布式事务保证订单状态和库存数量的一致性。
消息队列怎么保证消费者的消息不丢失的?
保证消费者消息不丢失的核心是手动 ACK + 健壮的消费逻辑,结合持久化和限流提升可靠性。若出现异常,通过死信队列和重试机制兜底,最终实现消息的可靠消费。
5.RabbitMQ如何保证消息的顺序性
RabbitMQ怎么保证消息的顺序性?
如何保证消息能够有序消费
1. 单队列单消费者模式
- 将所有消息发送到同一个队列
- 使用单个消费者绑定该队列
- 优点:天然保证消息顺序性
- 缺点:性能瓶颈,无法水平扩展
2. 路由键分组策略
- 按业务维度设计路由键(如 user_id)
- 相同路由键的消息路由到同一队列
- 每个队列配置独立消费者组
- 示例:订单消息按 user_id 哈希路由到不同队列
3. 消费者端处理
- 保持消息处理逻辑的幂等性
- 使用本地缓存维护消息顺序(如 Redis 有序集合)
- 实现重试机制时保持顺序重试
- 处理耗时操作时使用异步线程池但保证结果合并顺序
4. 生产者保障
- 使用事务或 publisher confirm 模式确保消息发送顺序
- 批量发送时保持批次内顺序
- 避免跨线程并发发送同一业务线消息
5. 高级特性组合
- 结合死信队列处理异常消息
- 使用优先级队列保障关键消息优先
- 配合消息时间戳实现延迟队列顺序消费
实现关键点:
- 顺序性与吞吐量是对立指标,需根据业务需求权衡
- 建议采用业务逻辑分片(如分库分表策略)来实现局部有序
- 监控队列积压情况,避免消息堆积导致顺序混乱
- 定期校验消息序号连续性(可通过消息头携带 Sequence ID)
实际应用中,可根据业务场景选择组合方案。例如电商订单系统可采用路由键分组 + 单消费者队列的方式,在保证订单维度消息顺序的同时,通过多队列实现整体吞吐量提升。
6.如何保证消息消费时的幂等性
消息或请求存在重复消费问题吗? RabbitMQ怎么保证消息不重复消费
RabbitMQ 可能会出现消息重复消费的问题,比如在消费者从 RabbitMQ 获取消息后,还未完成处理就发生了网络故障或其他异常,导致 RabbitMQ 认为消息没有被正确处理而重新投递,就可能造成重复消费。以下是一些保证消息不重复消费的方法:
1. 利用消息的唯一标识
a. 在消息生产者端:为每条消息生成一个全局唯一的标识,例如使用 UUID。将这个唯一标识与消息一起发送到 RabbitMQ。
b. 在消息消费者端:消费者在处理消息前,先检查该消息的唯一标识是否已经被处理过。可以使用数据库、缓存(如 Redis)等来记录已经处理过的消息标识。当收到一条新消息时,首先查询数据库或缓存,看是否已经存在该标识。如果存在,说明是重复消息,直接丢弃;如果不存在,则进行正常的消息处理流程,并在处理完成后将该消息标识存入数据库或缓存。
2. 基于数据库的事务机制
a. 在消息消费者端:将消息处理逻辑和消息状态更新放在同一个数据库事务中。例如,在处理一条订单消息时,将订单数据的插入或更新操作与记录消息已处理的操作放在一个事务中。如果消息处理成功,事务提交,消息状态更新为已处理;如果处理过程中出现异常,事务回滚,消息状态仍为未处理,RabbitMQ 可以重新投递消息。这样可以保证消息要么被成功处理并记录为已处理,要么不做任何更改等待重新处理,避免了重复处理的情况。
3. 利用消息队列的确认机制
a. 在消息消费者端:消费者在成功处理完消息后,再向 RabbitMQ 发送确认消息。RabbitMQ 只有收到确认消息后才会将消息从队列中删除。如果消费者在处理消息过程中出现故障,没有发送确认消息,RabbitMQ 会认为消息没有被成功处理,会重新投递消息。通过这种方式,确保每条消息都能被正确处理且仅处理一次。不过需要注意在消费者处理消息时间较长的情况下,可能需要合理设置 RabbitMQ 的相关参数,如heartbeat
等,以避免被 RabbitMQ 误认为消费者已失联而重新投递消息。
4. 幂等性处理
a. 在业务逻辑层面:设计业务逻辑时,使业务操作具有幂等性,即多次执行相同的操作,结果与执行一次相同。以更新用户积分的操作为例,假设消息内容是给用户 ID 为 123 的用户增加 10 积分。在数据库中,可以使用UPDATE user_score SET score = score + 10 WHERE user_id = 123
这样的语句来更新积分,无论这条消息被消费多少次,用户的积分只会增加一次。这样即使出现消息重复消费,也不会对业务数据造成影响。
7.RabbitMQ有哪些特性
RabbitMQ的死信队列以及应⽤场景
死信队列的概念
当消息在 RabbitMQ 中成为死信(Dead Letter)时,它会被重新发送到一个特定的队列,这个队列就是死信队列。消息成为死信的情况通常有以下几种:
- 消息被拒绝:消费者使用
basic.reject
或basic.nack
方法拒绝消息,并且没有设置requeue=true
,那么该消息会成为死信。- 消息过期:通过设置队列的
x-message-ttl
参数或消息的expiration
属性,当消息在队列中停留的时间超过了设置的过期时间,就会变成死信。- 队列达到最大长度:当队列设置了
x-max-length
或x-max-length-bytes
参数,达到了最大长度或最大字节数时,新进入队列的消息会被丢弃或成为死信,取决于具体配置。
死信队列的工作原理
一般来说,要使用死信队列,需要先声明一个正常的队列和一个死信队列,以及相应的交换机。正常队列通过设置x-dead-letter-exchange
和x-dead-letter-routing-key
参数来指定死信交换机和路由键。当正常队列中的消息成为死信后,会根据设置的死信交换机和路由键被发送到死信队列中,后续可以对死信队列中的消息进行相应处理,比如记录日志、重新发送等。
死信队列的应用场景
- 消息重试机制:当消息消费失败时,可以先将消息发送到死信队列。在死信队列的消费者中,可以根据一定的策略对消息进行重试,例如设置重试次数、重试间隔等。如果重试一定次数后仍然失败,可以将消息记录下来或者进行其他特殊处理,避免消息丢失。
- 数据清理与补偿:在一些数据同步或批量处理的场景中,如果部分消息处理失败成为死信,可以从死信队列中获取这些消息,分析失败原因,进行数据清理或者补偿操作,以保证数据的一致性和完整性。
- 监控与告警:通过监控死信队列中的消息数量、类型等信息,可以及时发现系统中可能存在的问题,比如消费者出现故障导致大量消息积压成为死信,或者某些特定类型的消息频繁出现消费失败等情况。可以根据死信队列的状态设置告警机制,及时通知运维人员或开发人员进行处理。
- 异步任务超时处理:在异步任务处理中,有些任务可能有执行时间限制。例如,一个订单创建后,如果在一定时间内没有收到支付成功的消息,就可以将订单相关的消息发送到死信队列,然后根据死信队列中的消息来进行订单超时取消等操作。
- 异常流量控制:当系统遇到突发的异常流量或者异常消息时,正常队列可能会被大量无效或异常消息填满。通过死信队列可以将这些异常消息隔离出来,避免它们影响正常业务流程的处理,同时可以对死信队列中的异常消息进行分析,找出流量异常的原因并采取相应的措施。
8.介绍下RabbitMQ的延迟队列
1. 概念
RabbitMQ 延迟队列是一种允许消息在指定的时间之后才被消费者消费的特殊队列。在常规的消息队列中,消息一旦被发送到队列,消费者就可以立即获取并处理。而延迟队列打破了这种即时性,它可以让消息在设定的延迟时间到达后才进入可消费状态,使得消息的处理在时间上具有一定的延迟性。
2. 应用场景
- 订单超时处理:在电商系统中,当用户创建订单后,如果在一定时间内(如 30 分钟)没有完成支付,系统需要自动取消该订单。可以将订单消息发送到延迟队列,设置延迟时间为 30 分钟,30 分钟后消息出队,系统根据消息内容取消对应的订单。
- 缓存预热:对于一些经常被访问的数据,为了提高系统的响应速度,可以在系统启动后一段时间或者特定时间点,将数据的预热任务消息发送到延迟队列。当延迟时间到达,消息被消费,触发缓存预热操作,提前将数据加载到缓存中。
- 消息重试机制:当消息消费失败时,不立即进行重试,而是将消息发送到延迟队列,设置一定的延迟时间(如 5 分钟)后再进行重试。这样可以避免因网络抖动等短暂问题导致的频繁重试,同时也给系统一定的恢复时间。
- 定时提醒:在社交、办公等应用中,需要给用户发送定时提醒消息。例如,会议开始前 15 分钟提醒参会人员,将提醒消息发送到延迟队列,设置延迟时间为 15 分钟,时间到达后消息出队并发送提醒给用户。
3. 实现方式
利用 TTL(Time-To-Live)和死信队列
- 原理:TTL 是指消息的存活时间,RabbitMQ 允许为队列或消息单独设置 TTL。当消息的 TTL 到期后,如果消息所在的队列配置了死信交换机和路由键,消息会被发送到死信队列。通过设置消息的 TTL 来实现延迟效果,当消息到达死信队列时,消费者从死信队列中消费消息,从而达到延迟消费的目的。
- 实现步骤
- 声明正常队列和死信队列:创建一个正常队列,并为其设置
x-dead-letter-exchange
和x-dead-letter-routing-key
参数,指定死信交换机和路由键。同时声明死信队列和对应的死信交换机。- 设置消息 TTL:在发送消息时,通过设置消息的
expiration
属性或者在队列上设置x-message-ttl
参数来指定消息的存活时间。- 消费者监听死信队列:消费者监听死信队列,当消息因 TTL 到期进入死信队列后,消费者进行消费。
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;public class DelayQueueExample {private static final String NORMAL_EXCHANGE = "normal_exchange";private static final String NORMAL_QUEUE = "normal_queue";private static final String DEAD_LETTER_EXCHANGE = "dead_letter_exchange";private static final String DEAD_LETTER_QUEUE = "dead_letter_queue";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 声明死信交换机和死信队列channel.exchangeDeclare(DEAD_LETTER_EXCHANGE, "direct");channel.queueDeclare(DEAD_LETTER_QUEUE, true, false, false, null);channel.queueBind(DEAD_LETTER_QUEUE, DEAD_LETTER_EXCHANGE, "routing_key");// 声明正常交换机和正常队列,并设置死信交换机和路由键Map<String, Object> argsMap = new HashMap<>();argsMap.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);argsMap.put("x-dead-letter-routing-key", "routing_key");channel.exchangeDeclare(NORMAL_EXCHANGE, "direct");channel.queueDeclare(NORMAL_QUEUE, true, false, false, argsMap);channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "routing_key");// 发送消息并设置 TTLString message = "Delayed message";channel.basicPublish(NORMAL_EXCHANGE, "routing_key", null, message.getBytes());channel.basicPublish(NORMAL_EXCHANGE, "routing_key", null, message.getBytes());System.out.println(" [x] Sent '" + message + "'");channel.close();connection.close();}
}
使用 RabbitMQ 插件(rabbitmq_delayed_message_exchange)
- 原理:该插件为 RabbitMQ 提供了专门的延迟消息交换器类型。通过使用这个插件,可以直接在交换机层面实现消息的延迟,而不需要依赖 TTL 和死信队列的组合。
- 实现步骤
- 安装插件:将
rabbitmq_delayed_message_exchange
插件安装到 RabbitMQ 服务器上,并启用该插件。- 声明延迟交换机:在代码中声明一个类型为
x-delayed-message
的交换机。- 发送消息并设置延迟时间:在发送消息时,通过设置消息的
x-delay
属性来指定延迟时间,单位为毫秒。- 消费者监听队列:消费者监听与延迟交换机绑定的队列,当延迟时间到达后,消息会被发送到队列,消费者进行消费。
介绍下RabbitMQ的⼯作模式
看下边的博客
RabbitMQ 7种工作模式详解及应用场景_rabbitmq 广播模式应用场景-CSDN博客
10.消息积压的原因, 如何处理
RabbitMQ 消息积压是指在消息队列中,消息的产生速度远远大于消息的消费速度,导致大量消息在队列中堆积,不能及时被处理。以下是消息积压的常见原因及处理方法:
消息积压的原因
- 消费者处理能力不足:消费者的消费速度跟不上生产者的生产速度。可能是因为消费者的业务逻辑复杂,处理每条消息需要耗费较长时间,也可能是消费者的资源(如 CPU、内存、网络等)有限,无法处理大量的消息。
- 生产者发送消息速度过快:生产者在短时间内产生了大量的消息并发送到 RabbitMQ 中,超过了 RabbitMQ 和消费者的处理能力。
- 网络问题:网络不稳定、延迟高或出现短暂中断等情况,会导致消息发送或消费过程受阻。例如,消费者与 RabbitMQ 之间的网络连接不稳定,可能会导致消息确认延迟,使得 RabbitMQ 不能及时将消息标记为已消费,从而造成消息积压。
- RabbitMQ 配置不合理:如队列的容量设置过小,无法容纳大量的消息;或者内存、磁盘等资源限制设置不合理,当消息量达到一定程度时,RabbitMQ 性能下降,导致消息处理速度变慢。
- 消费者故障或异常:消费者程序出现故障、崩溃或陷入死循环等问题,无法正常消费消息。如果没有及时发现并修复,就会导致消息不断积压。
- 消息重试机制问题:当消息消费失败时,如果重试机制设置不合理,例如重试间隔过短、重试次数过多等,可能会导致大量消息在重试过程中积压。
处理消息积压的方法
- 增加消费者数量:可以通过增加消费者的实例数量来提高消费能力,使消息能够更快地被处理。可以根据消息积压的程度和系统资源情况,合理地增加消费者数量。
- 优化消费者性能:对消费者的业务逻辑进行优化,减少处理每条消息的时间。例如,优化数据库查询语句、减少不必要的计算和操作等。同时,确保消费者有足够的资源(如 CPU、内存等)来处理消息,可以考虑对消费者所在的服务器进行升级或扩容。
- 限流生产者:如果是生产者发送消息速度过快导致积压,可以对生产者进行限流,控制消息的发送速度,使其与消费者的处理能力相匹配。可以使用令牌桶算法、漏桶算法等限流算法来实现。
- 检查和优化网络:检查网络设备和连接,确保网络稳定。可以增加网络带宽、优化网络拓扑结构等,减少网络延迟和丢包,提高消息发送和消费的效率。
- 调整 RabbitMQ 配置:根据实际情况合理调整 RabbitMQ 的配置参数。例如,增加队列的容量,调整内存和磁盘的使用限制等,以提高 RabbitMQ 处理消息的能力。
- 死信队列处理:可以将积压的消息转移到死信队列中,然后对死信队列中的消息进行单独处理。分析消息积压的原因,针对不同情况采取相应的措施,如修复消费者故障、调整业务逻辑等,再从死信队列中重新消费这些消息。
- 消息清理和补偿:如果积压的消息中有一些是可以丢弃的(如过期的消息、不重要的重复消息等),可以考虑进行清理。对于一些需要保证数据完整性的消息,可以在处理完积压消息后,进行数据补偿操作,确保数据的一致性。
11.RabbitMQ是推模式还是拉模式
RabbitMQ 同时支持推模式(Push)和拉模式(Pull),以下为你详细介绍这两种模式:
推模式(Push)
原理
在推模式下,当 RabbitMQ 中的队列有新消息时,RabbitMQ 服务器会主动将消息推送给消费者。消费者在启动时会与 RabbitMQ 建立连接,并声明要消费的队列,然后通过特定的 API 告知 RabbitMQ 自己准备好接收消息。RabbitMQ 会根据消费者的配置和队列情况,将消息推送给消费者。
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class PushConsumer {private final static String QUEUE_NAME = "push_queue";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}
特点
- 实时性高:消息一旦到达队列,会立即被推送给消费者进行处理,能及时响应新消息的到来。
- 减少消费者的轮询开销:消费者无需主动去询问队列是否有消息,降低了消费者的资源消耗。
- 可能导致消费者压力大:如果生产者发送消息的速度过快,而消费者处理能力有限,可能会使消费者不堪重负,出现消息积压或处理不及时的情况。
拉模式(Pull)
原理
在拉模式下,消费者需要主动向 RabbitMQ 发送请求来获取消息。消费者通过调用特定的 API 从队列中拉取消息,每次拉取操作可以指定拉取的消息数量。这种模式下,消费者对消息的获取具有更大的控制权。
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class PullConsumer {private final static String QUEUE_NAME = "pull_queue";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);GetResponse response = channel.basicGet(QUEUE_NAME, true);if (response != null) {String message = new String(response.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");} else {System.out.println(" [x] No message available");}channel.close();connection.close();}
}
特点
- 消费者可控性强:消费者可以根据自身的处理能力和业务需求,灵活地决定何时拉取消息以及拉取多少消息,避免了因消息推送过快而导致的处理压力过大问题。
- 实时性较差:消费者需要主动去拉取消息,如果拉取间隔设置不合理,可能会导致消息处理不及时,存在一定的延迟。
- 增加了消费者的实现复杂度:消费者需要实现轮询拉取消息的逻辑,相比推模式,代码实现更为复杂。
模式选择建议
- 推模式:适用于对消息实时性要求较高、消费者处理能力较强且稳定的场景,例如实时日志处理、实时监控数据处理等。
- 拉模式:适用于消费者处理能力不稳定、需要根据自身负载动态调整消息获取速度的场景,或者对消息处理的顺序和时机有严格要求的场景。、
整理不易,有帮助可以点个赞,感谢阅览!!
相关文章:
RabbitMQ应用问题大全(精心整理版)
前言 其实这部分知识我是整理在语雀上了,这里是直接复制粘贴过来的。不是很好阅读,可以直接点下方链接去语雀看,那个看的会舒服很多。 https://www.yuque.com/g/ngioig/upbg6b/fkarhyo8fpgrtyq8/collaborator/join?tokenGvlO0di8KaIfO8aF&am…...
【人工智能】卷积神经网络的奥秘:深度学习的视觉革命
卷积神经网络(CNN)是深度学习中处理图像、视频等高维数据的主流模型,因其局部特征提取和参数共享特性而效率高且效果优异。本文深入探讨了CNN的理论基础,包括卷积操作、池化层、激活函数和全连接层的数学原理,并通过LaTeX公式推导其前向传播和反向传播过程。接着,我们提供…...
掌握MiniQMT:程序化下单与撤单的高效实现
掌握MiniQMT:程序化下单与撤单的高效实现 🚀量化软件开通 🚀量化实战教程 在量化交易领域,程序化下单与撤单是实现自动化交易策略的关键环节。通过MiniQMT平台,我们可以高效地执行这些操作,从而快速响应…...
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好! 很久没写软文了,今天给大家带了一个干货,如上图,大疆Pocket 3加ENC编…...
Nacos学习笔记-占位符读取其他命名空间内容
Nacos当前命名空间下的配置文件需要跨命名空间读取其他配置文件的内容。可以先通过Nacos提供的API接口获取配置文件内容,然后解析数据将其放入环境的PropertySource中。 相关依赖包 <!-- Nacos依赖包 --> <dependency><groupId>com.alibaba.clo…...
每天五分钟深度学习框架PyTorch:使用残差块快速搭建ResNet网络
本文重点 前面我们使用pytorch搭建了残差块,本文我们更进一步,我们使用残差块搭建ResNet网络,当学会如何搭建残差块之后,搭建ResNet就会非常简单了,因为ResNet就是由多个残差块组成的。 残差块 残差块我们前面已经介…...
python操作java文件的一种方法
对于python操作java代码的场景来说,比较多的可能就是涉及加密的场景,尤其涉及到登录的场景,对于输入的账号密码可能会涉及到加密,如果开发告诉我们如何加密,那么,OK,我们可以直接通过代码去实现…...
自然语言处理:最大期望值算法
介绍 大家好,博主又来给大家分享知识了,今天给大家分享的内容是自然语言处理中的最大期望值算法。那么什么是最大期望值算法呢? 最大期望值算法,英文简称为EM算法,它的核心思想非常巧妙。它把求解模型参数的过程分成…...
leetcode-sql数据库面试题冲刺(高频SQL五十题)
题目: 197.上升的温度 表: Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是该表具有唯一值的列。 没有具有相同 recordDate …...
开发者社区测试报告(功能测试+性能测试)
功能测试 测试相关用例 开发者社区功能背景 在当今数字化时代,编程已经成为一项核心技能,越来越多的人开始学习编程,以适应快速变化的科技 环境。基于这一需求,我设计开发了一个类似博客的论坛系统,专注于方便程序员…...
环形链表问题的探究与代码实现
在数据结构与算法的学习中,环形链表是一个经典的问题。它不仅考察对链表这种数据结构的理解,还涉及到指针操作和逻辑推理。本文将结合代码和图文,深入分析如何判断链表中是否有环以及如何找到环的入口点。 目录 一、判断链表中是否有环 …...
【C++】vector(下):vector类的模拟实现(含迭代器失效问题)
文章目录 前言一、vector类的常用接口的模拟实现1.头文件(my vector.h)整体框架2.模拟实现vector类对象的常见构造3.模拟实现vector iterator4.模拟实现vector类对象的容量操作5.模拟实现vector类对象的访问6.模拟实现vector类对象的修改操作 二、vector…...
NLTK和jieba
NLTK与jieba概述 自然语言处理(NLP)领域是计算机科学领域与人工智能领域中的一个重要方向,主要研究方向是实现人与计算机之间用自然语言进行有效通信的各种理论和方法。 在自然语言处理领域中,文本类型的数据占据着很大的市场&a…...
Java后端高频面经——计算机网络
TCP/IP四层模型?输入一个网址后发生了什么,以百度为例?(美团) (1)四层模型 应用层:支持 HTTP、SMTP 等最终用户进程传输层:处理主机到主机的通信(TCP、UDP&am…...
CSDN博客:Markdown编辑语法教程总结教程(中)
❤个人主页:折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定,高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…...
Springboot redis bitMap实现用户签到以及统计,保姆级教程
项目架构,这是作为demo展示使用: Redis config: package com.zy.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.Ob…...
AI Agent系列(一) - Agent概述
AI Agent系列【一】 前言一、AI代理的特点二、 AI Agent的技术框架三、 开源自主代理 前言 AI Agent,即人工智能代理,一般直接叫做智能体 百度百科给AI Agent定义为: “以大语言模型为大脑驱动的系统,具备自主理解、感知、规划、…...
Scala 中trait的线性化规则(Linearization Rule)和 super 的调用行为
在 Scala 中,特质(Trait)是一种强大的工具,用于实现代码的复用和组合。当一个类混入(with)多个特质时,可能会出现方法冲突的情况。为了解决这种冲突,Scala 引入了最右优先原则&#…...
【Linux系统编程】初识系统编程
目录 一、什么是系统编程1. 系统编程的定义2. 系统编程的特点3. 系统编程的应用领域4. 系统编程的核心概念5. 系统编程的工具和技术 二、操作系统四大基本功能1. 进程管理(Process Management)2. 内存管理(Memory Management)3. 文…...
Unsloth - 动态 4 bit 量化
文章目录 💔 量化可能会破坏模型🦙 Llama 3.2 Vision 细节Pixtral (12B) 视觉🦙 Llama 3.2 (90B) 视觉指令 本文翻译自:Unsloth - Dynamic 4-bit Quantization (2024年12月4日 Daniel & Michael https://unsloth.…...
技术领域,有许多优秀的博客和网站
在技术领域,有许多优秀的博客和网站为开发者、工程师和技术爱好者提供了丰富的学习资源和行业动态。以下是一些常用的技术博客和网站,涵盖了编程、软件开发、数据科学、人工智能、网络安全等多个领域: 1. 综合技术博客 1.1 Medium 网址: ht…...
黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!
调色教程 针对人像、静物以及户外旅拍照片,运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具,如基本参数调整、HSL(色相、饱和度、明亮度)调整、曲线工具等改变照片原本的色彩、明度、对比度等属性,将…...
Manus 与鸿蒙 Next 深度融合:构建下一代空间计算生态
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/north 文章目录 一、技术融合背景与意义1.1 技术栈协同优势1.2 典型应用场景 二、系统架构设计2.1 整体架构图…...
并查集模板
注意理解路径压缩 static class UnionFind {int[] fa;public UnionFind(int n) {fa new int[n];for (int i 0; i < n; i) {fa[i] i;}}public int find(int i) {if (fa[i] ! i) {fa[i] find(fa[i]);}return fa[i];}public void union(int i, int j) {int fai find(i);in…...
推流项目的ffmpeg配置和流程重点总结一下
ffmpeg的初始化配置,在合成工作都是根据这个ffmpeg的配置来做的,是和成ts流还是flv,是推动远端还是保存到本地, FFmpeg 的核心数据结构,负责协调编码、封装和写入操作。它相当于推流的“总指挥”。 先来看一下ffmpeg的…...
使用 Python 开发的简单招聘信息采集系统
以下是一个使用 Python 开发的简单招聘信息采集系统,它包含用户登录、招聘信息收集和前后端交互的基本功能。我们将使用 Flask 作为后端框架,HTML 作为前端页面。 项目结构 recruitment_system/ ├── app.py ├── templates/ │ ├── login.html │ ├── index…...
Selenium库打开指定端口(9222、9333等)浏览器【已解决!!!】
就是在写动态爬虫爬取数据的过程中,如果用selenium的话,有一个缺点,就是当我们去测试一个网站能不能爬取,它都会重新换端口打开一个浏览器,不会使用上一次使用的浏览器,在实际使用过程中这样调试很烦&#…...
Android MVI架构模式详解
MVI概念 MVI(Model-View-Intent)是一种Android应用架构模式,旨在通过单向数据流和不可变性来简化应用的状态管理。MVI的核心思想是将用户操作、状态更新和界面渲染分离,确保应用的状态可预测且易于调试。 MVI的核心组件 Model&a…...
低代码开发直聘管理系统
低代码 DeepSeek 组合的方式开发直聘管理系统,兼职是开挂的存在。整个管理后台系统 小程序端接口的输出,只花了两个星期不到。 一、技术栈 后端:SpringBoot mybatis MySQL Redis 前端:Vue elementui 二、整体效果 三、表结…...
LVGL开发说明
准备工作 LVGL图形化工具:Gui-Guider-Setup-1.8.0-GA.exeLVGL库:lvgl-release-v8.3屏幕触摸驱动:CST816屏幕驱动:ST7789屏幕尺寸:320 * 170 触发事件 按键的点击事件 添加点击事件 触摸屏点击对应的按键后就会触发回…...
推荐优秀的开源软件合集
在信息化高度发达的今天,数据安全与远程协作变得越来越重要。很多企业和个人都在寻找可替代商业闭源软件的开源解决方案。今天,我们向大家推荐几款优秀的开源软件,涵盖私有云存储、远程桌面、团队协作、内容管理等多个领域。 1. Nextcloud —…...
代码随想录刷题day41|(二叉树篇)二叉树的最大深度(递归)
目录 一、二叉树理论基础 二、二叉树的深度和高度 三、递归和迭代思路 3.1 递归法 3.2 迭代法 四、相关算法题目 五、总结 一、二叉树理论基础 详见:代码随想录刷题day34|(二叉树篇)二叉树的递归遍历-CSDN博客 二、二叉树的深度和高…...
向量内积(点乘)和外积(叉乘)
文章目录 1. 向量的内积(点积)1.1 定义1.2 几何意义表征两个向量的投影关系计算向量夹角的余弦值 1.3 重要性质1.4 应用场景 2. 向量的外积(叉积)2.1 定义(仅适用于三维空间)2.2 几何意义2.3 重要性质2.4 应…...
PDF转JPG(并去除多余的白边)
首先,手动下载一个软件(poppler for Windows),下载地址:https://github.com/oschwartz10612/poppler-windows/releases/tag/v24.08.0-0 否则会出现以下错误: PDFInfoNotInstalledError: Unable to get pag…...
【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)
效果一览 代码获取私信博主基于麻雀搜索算法(SSA)的无人机路径规划(Matlab) 一、算法背景与核心思想 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种受麻雀群体觅食行为启发的元启发式算法࿰…...
2020CVPR-SiamBAN:用于视觉跟踪的Siamese框自适应网络
原文标题:Siamese Box Adaptive Network for Visual Tracking 中文标题:用于视觉跟踪的Siamese框自适应网络 代码地址: GitHub - hqucv/siamban: Siamese Box Adaptive Network for Visual Tracking Abstract 大多数现有的跟踪器通常依靠多尺…...
带你从入门到精通——自然语言处理(五. 自注意力机制和transformer的输入部分)
建议先阅读我之前的博客,掌握一定的自然语言处理前置知识后再阅读本文,链接如下: 带你从入门到精通——自然语言处理(一. 文本的基本预处理方法和张量表示)-CSDN博客 带你从入门到精通——自然语言处理(二…...
MySql自动安装脚本
一、脚本安装流程 1. 添加MySQL的Repository 使用wget命令从MySQL官方网站下载Yum Repository的RPM包。使用rpm -ivh命令安装下载的RPM包,以添加MySQL的Yum Repository。 2. 安装mysql-community-server 使用yum install -y mysql-community-server --nogpgchec…...
3.9【Q】csd
在计算机存储领域,CSD是什么? 基于CXL™-Type3 实现内存池化 CPU访问内存的瓶颈是什么?具体矛盾是什么? 计算型存储-2:标准、API实现 NUMA是什么?详细解释一下它的核心思想?...
Qt常用控件之表格QTableWidget
表格QTableWidget QTableWidget 是一个表格控件,行和列交汇形成的每个单元格,是一个 QTableWidgetItem 对象。 1. QTableWidget属性 QTableWidget 的属性只有两个: 属性说明rowCount当前行的个数。columnCount当前列的个数。 2. QTableW…...
数据库批处理
数据库批处理是一种处理数据的方法,通常用于对大量数据进行一次性操作。批处理可以有效地减少数据库操作的次数,提高数据处理的效率。在数据库中,批处理通常通过编写批处理脚本或使用相应的工具来实现。 一般情况下,数据库批处理…...
Flask 框架简介
Flask 框架简介 Flask 框架简介 Flask 框架简介 Flask 是一个 Python 微型网页开发框架。微型指明了 Flash 的核心是轻量级的,但是可以灵活扩展。下面的简单的例子要和一个数据库系统交互。Django附带了与最常见的数据库交互所需的库。另一方面,Flask允…...
KMP 算法的 C 语言实现
# include <stdio.h> # include <stdlib.h> # include <string.h>// 打印 KMP 匹配结果. void ColorPrint(char *T, int *result, int result_size, int m) {int green_size strlen("\x1b[31m");int reset_size strlen("\x1b[0m");cha…...
深入理解 TCP 协议:可靠传输、连接管理与经典面试题解析
TCP(Transmission Control Protocol)是互联网中最重要的传输层协议之一,其设计目标是提供可靠的、面向连接的、全双工的数据传输服务。本文将从核心机制、工作原理到经典面试题,全面解析 TCP 协议的关键特性。 一、TCP 核心特性 …...
雪花算法
雪花算法(Snowflake) 雪花算法是一种由Twitter开源的分布式ID生成算法,广泛应用于分布式系统中,用于生成全局唯一的ID。这些ID不仅具有唯一性,还按照时间顺序递增,便于排序和查询。以下是雪花算法的详细解…...
coding ability 展开第二幕(双指针——巩固篇)超详细!!!!
文章目录 前言有效的三角形个数思路 查找总价格为目标值的两个商品思路 两数之和思路 三数之和思路 四数之和思路 总结 前言 本专栏的上篇,讲述了双指针的一些基础的算法习题 今天我们来学习更进一步的双指针用法吧 其实也是大相径庭,和前面的差不多&…...
系统安全阶段练习真题(高软44)
系列文章目录 系统安全阶段练习真题 文章目录 系列文章目录前言一、真题总结 前言 本节就是系统安全的阶段练习真题,带答案与解析。 一、真题 总结 就是高软笔记,大佬请略过!...
Mybatis Generator 使用手册
第一章 什么是Mybatis Generator? MyBatis Generator Core – Introduction to MyBatis Generator MyBatis生成器(MBG)是MyBatis框架的代码生成工具。它支持为所有版本的MyBatis生成代码,通过解析数据库表(或多个表&…...
Android中AIDL和HIDL的区别
在Android中,AIDL(Android Interface Definition Language) 和 HIDL(HAL Interface Definition Language) 是两种用于定义跨进程通信接口的语言。AIDL 是 Android 系统最早支持的 IPC(进程间通信࿰…...
Gazebo 启动时候配置物体
1. 准备模型 mkdir -p ~/.gazebo/models/table echo export GAZEBO_MODEL_PATH$HOME/.gazebo/models:$GAZEBO_MODEL_PATH >> ~/.bashrc source ~/.bashrc # 从https://github.com/osrf/gazebo_models下载模型 # 桌子 cd ~/.gazebo/models/table wget https://raw.github…...