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

深度剖析 RocketMQ 5.0 之架构解析:云原生架构如何支撑多元化场景?

拓展学习:🔍「RocketMQ 中文社区」 持续更新,提供 RocketMQ 领域专家模型的 AI 答疑

作者 | 隆基

简介: 了解 RocketMQ 5.0 的核心概念和架构概览;然后我们会从集群角度出发,从宏观视角学习 RocketMQ 的管控链路、数据链路、客户端和服务端如何交互;学习 RocketMQ 如何实现数据的存储,数据的高可用,如何利用云原生存储进一步提升竞争力。

1.前言

从初代开源消息队列崛起,到 PC 互联网、移动互联网爆发式发展,再到如今 IoT、云计算、云原生引领了新的技术趋势,消息中间件的发展已经走过了 30 多个年头。

目前,消息中间件在国内许多行业的关键应用中扮演着至关重要的角色。随着数字化转型的深入,客户在使用消息技术的过程中往往同时涉及交叉场景,比如同时进行物联网消息、微服务消息的处理,同时进行应用集成、数据集成、实时分析等,企业需要为此维护多套消息系统,付出更多的资源成本和学习成本。

在这样的背景下,2022 年,RocketMQ 5.0 正式发布,相对于 RocketMQ 4.0,架构走向云原生化,并且覆盖了更多的业务场景。想要掌握最新版本 RocketMQ 的应用,就需要进行更加体系化的深入了解。

2.背景

本节课的内容是 RocketMQ 5.0 的架构解析。前面的课程中,我们了解到 RocketMQ 5.0 可以支撑多样化的业务场景,不仅仅是业务消息,它还会支持流处理、物联网、事件驱动等场景。在进入具体的业务领域场景之前,我们先从技术的角度来了解 RocketMQ 的云原生架构,看它是如何基于这一套统一的架构支撑多元化场景的。

首先,我们会了解 RocketMQ 5.0 的核心概念和架构概览;然后我们会从集群角度出发,从宏观视角学习 RocketMQ 的管控链路、数据链路、客户端和服务端如何交互;最后,我们将回到消息队列最重要的模块存储系统,学习 RocketMQ 如何实现数据的存储,数据的高可用,如何利用云原生存储进一步提升竞争力。

3. 概览

3.1. RocketMQ 领域模型

在学习 RocketMQ 的架构之前,我们先从用户视角来来看 RocketMQ 的关键概念以及领域模型。如下图,我们按照消息的流转顺序来介绍。

最左边是消息生产者,一般对应业务系统的上游应用,在某个业务动作触发后发送消息到 Broker。Broker 是消息系统数据链路的核心,负责接收消息、存储消息、维护消息状态、消费者状态。多个 Broker 组成一个消息服务集群,共同服务一个或者多个 Topic 。刚才提到生产者生产消息并发送到 Broker,消息是业务通信的载体,每个消息包含消息 ID、消息 Topic、消息体内容、消息属性、消息业务 key 等。每条消息都属于某个 Topic,表示同一个业务语义,在阿里内部,我们交易消息的 Topic 叫做 Trade,购物车消息叫 Cart,生产者应用会把消息发送到对应的 Topic 上。Topic 里面还有 MessageQueue,这个用于消息服务的负载均衡和数据存储分片,每个 Topic 会包含一个或者多个 Message Queue 分布在不同的消息 Broker。生产者发送消息,Broker 存储消息,下一步就是消费者消费消息。消费者一般对应业务系统的下游应用,同一个消费者应用集群会共用一个 Consumer Group。消费者会和某个 Topic 产生订阅关系,订阅关系是 Consumer Group + Topic + 过滤表达式的三元组,符合订阅关系的消息就会被对应的消费者集群消费。接下来我们从技术实现角度进一步深入了解 RocketMQ 。

3.2. RocketMQ 5.0 架构概览

这是 RocketMQ 5.0 的架构概览图,从上往下看,可分为 SDK、NameServer、Proxy 和 Store 层。

我们首先来看 SDK 层,包括了 RocketMQ 的 SDK ,用户基于 RocketMQ 自身的领域模型来使用这个 SDK 。除了 RocketMQ 自身的 SDK 之外,还包括了细分领域场景的业界标准 SDK 。面向事件驱动的场景,RocketMQ 5.0 支持 CloudEvents 的 SDK;面向 IoT 的场景,RocketMQ 支持物联网 MQTT 协议的 SDK;为了方便更多的传统应用迁移到 RocketMQ,我们还支持了 AMQP 协议,未来也会开源到社区版本里。另外一个组件是是 NameServer,它承担服务发现和负载均衡的职责。通过 NameServer,客户端能获取 Topic 的数据分片和服务地址,链接消息服务器进行消息收发。

消息服务包含计算层 Proxy 和存储层 RocketMQ Store。RocketMQ 5.0 是存算分离的架构,这里的存算分离强调的是模块的分离,职责的分离。Proxy 和 RocketMQ Store 面向不同的业务场景可以合并部署,也可以分开部署。计算层 Proxy 主要承载的消息的上层业务逻辑,尤其是面向多场景、多协议的支持,比如承载 CloudEvents、MQTT、AMQP 的领域模型的实现逻辑和协议转换。面向不同的业务负载,还可以把 Proxy 分离部署,独立弹性,比如在物联网场景,Proxy 层独立部署可以面向海量物联网设备连接数进行弹性伸缩,和存储流量扩缩容解耦。RocketMQ Store 层则是负责核心的消息存储,这里包括基于 Commitlog 的存储引擎、多元索引、多副本技术和云存储集成扩展。消息系统的状态都下沉到 RocketMQ Store,其他组件全部实现无状态化。

4. 服务发现

4.1. 服务发现

第二部分我们来详细看一下 RocketMQ 的服务发现。RocketMQ 的服务发现是通过 NameServer(简称NS) 来实现的。

我们通过下方这个图来了解服务发现的机制,这个是 Proxy 和 Broker 合并部署的模式,也是 RocketMQ 最常见的模式。前面提到每个 Broker 集群会负责某些 Topic 的服务,每个 Broker 都会把自身服务哪些 Topic 注册到 NameServer 集群,和每个 NameServer 进行通信,并定时和 NS 通过心跳机制来维持租约。服务注册的数据结构包含 Topic 和 Topic 分片 MessageQueue。

在示例中 Broker1 和 Broker2 分别承载 TopicA 的一个分片。在 NS 机器上会维护全局视图,TopicA 有两个分片分别在 Broker1 和 Broker2 。RocketMQ SDK 在对 TopicA 进行正式的消息收发之前,它会随机访问一个 NameServer 机器,从而知道这个 TopicA 有哪些分片,每个数据的分片在哪个 Broker 上面,它会跟这些 Broker 建立好长连接,然后再进行消息的收发。大部分的项目的服务发现机制会通过 zookeeper 或者 etcd 等强一致的分布式协调组件来担任注册中心的角色,而 RocketMQ 有自己的特点,如果从 CAP 的角度来看,它的注册中心采用的是 AP 的模式,NameServer 节点无状态,是 ShareNothing 的架构,有更高的可用性。

再看下方这个图,我们说 RocketMQ 的存算分离是可分可合,这里采用的就是分离的部署模式,RocketMQ SDK 直接访问无状态的 Proxy 集群。这个模式可以应对更加复杂的网络环境,支持多网络类型的访问,如公网访问,实现更好的安全控制。

在整个服务发现机制中,NameServer、Proxy 都是无状态的,可以随时进行节点增减。有状态节点 Broker 的增减基于 NS 的注册机制,客户端可以实时感知、动态发现。在缩容过程中,RocketMQ Broker 还可以进行服务发现的读写权限控制,对缩容的节点禁写开读,待未读消息全消费,实现无损平滑下线。

4.2. 负载均衡

刚才我们已经知道 SDK 如何通过 NameServer 来发现 Topic 的分片信息 MessageQueue,以及 Broker 地址。基于这些服务发现的元数据,我们再来详细看看消息流量是如何在生产者、RocketMQ Broker 和消费者集群进行负载均衡的。

先来看生产链路的负载均衡,生产者通过服务发现机制,知道了 Topic 的数据分片以及对应的 Broker 地址。它的服务发现机制是比较简单的,在默认情况下采用 Round Robin 的方式轮询发送到各个 Topic 队列,保证了 Broker 集群的流量均衡。在顺序消息的场景下会略有特殊,会基于消息的业务主键 Hash 到某个队列发送,这样一来,如果有热点业务主键,那 Broker 集群也可能出现热点。除此之外,我们基于这些元数据还能根据业务需要扩展更多的负载均衡算法,比如同机房优先算法,可以降低多机房部署场景下的延迟,提升性能。

再看消费者的负载均衡,相对来说会比生产者更复杂,它有两种类型的负载均衡方式。最经典的模式是队列级负载均衡,消费者知道 Topic 的队列总数,也知道同一个 Consumer Group 下的实例数,就可以按照统一的分配算法,类似一致性 hash 的方式,让每个消费者实例绑定对应的队列,只消费绑定队列的消息,每个队列的消息也只会被一个消费者实例消费。

这种模式最大的缺点就是负载不均衡,消费者实例要绑定队列、有临时状态。如果我们有三个队列,有两个消费者实例,那就必然有一个消费者需要消费三分之二的数据,如果我们有四个消费者,那么第四个消费者就要空跑。所以在 RocketMQ 5.0 里面,我们引入了消息粒度的负载均衡机制,无需绑定队列,消息在消费者集群随机分发,这样就可以保障消费者集群的负载均衡。更重要的是这种模式更加符合未来 Serverless 化的趋势,Broker 的机器数、Topic 的队列数和消费者实例数完全解耦,可以独立扩缩容。

5. 存储系统

前面通过架构概览和服务发现机制,我们已经对 RocketMQ 有比较全局性的了解。接下来我们将深入 RocketMQ 的存储系统,这个模块对 RocketMQ 的性能、成本、可用性有决定性作用。

5.1. 存储核心

先来看一下 RocketMQ 的存储核心。存储核心由 Commitlog、Consumequeue 和 Index 文件组成。消息存储首先写到 Commitlog,刷盘并复制到 slave 节点来完成持久化,Commitlog 是 RocketMQ 存储的 source of true,通过它可以构建完整的消息索引。相比于 Kafka 而言,RocketMQ 把所有 Topic 的数据都写到 Commitlog 文件,最大化顺序 io,使得 RocketMQ 单机可以支撑万级的 Topic。

在写完 Commitlog 之后,RocketMQ 会异步分发出多个索引,首先是 ConsumeQueue 索引,这个和 MessageQueue 是对应的,基于这个索引可以实现消息的精准定位,可以按照 Topic、队列 id 和位点定位到消息,消息回溯功能也是基于这个实现的。另外一个很重要的索引是哈希索引,它是消息可观测的基础。通过持久化的 hash 表来实现消息业务主键的查询能力,消息轨迹主要是基于这个来实现的。

除了消息本身的存储之外,Broker 还承载了消息元数据的存储。包括 topics 的文件,表示该 Broker 会对哪些 Topic 提供服务,还维护了每个 Topic 队列数、读写权限、顺序性等属性。还有一个 Subscription、ConsumerOffset 文件,这两个维护了 Topic 的订阅关系以及每个消费者的消费进度。还有 Abort、Checkpoint 文件则是用于完成重启后的文件恢复,保障数据完整性。

5.2. Topic 高可用

上面的内容中,我们站在单机的视角,从功能的层面学习 RocketMQ 的存储引擎,包括 Commitlog 和索引。现在我们重新跳出来,再从集群视角看 RocketMQ 的高可用。我们先定义一下 RocketMQ 的高可用,指当 RocketMQ 集群出现 NameServer、Broker 局部不可用的时候,指定的 Topic 依然是可读可写的。

RocketMQ 可以应对三类故障场景。

第一种 case,某对主备单机不可用。如下方这个图,当 Broker2 主宕机,备可用。TopicA 依然可读可写,其中分片1可读可写,分片 2 可读不可写,Topic A 在分片 2 的未读消息依然可以消费。总结起来就是 Broker 集群里,只要任意一组 Broker 存活一个节点,Topic 的读写可用性不受影响。如果某组 Broker 主备全部宕机,那么 Topic 新数据的读写也不受影响,未读消息会延迟,待任意主备启动才能继续消费。

接下来,再看 NameServer 集群的故障情况,由于 NameServer 是 ShareNothing 的架构,每个节点都是无状态的,并且是 AP 模式,不需要依赖多数派算法,所以只要有一台 NameServer 存活,整个服务发现机制都是正常的,Topic 的读写可用性不受影响。

甚至在更极端的情况下,整个 NS 都不可用,由于 RocketMQ 的 SDK 对服务发现元数据有缓存,只要 SDK 不重启,它依然可以按照当下的 topic 元数据,继续进行消息收发。

5.3. MessageQueue 高可用

从 Topic 高可用的实现中我们发现,虽然 Topic 持续可读可写,但是 Topic 的读写队列数会发生变化。队列数变化,会对某些数据集成的业务有影响,比如说异构数据库 Binlog 同步,同一个记录的变更 Binlog 会写入不同的队列,重放 Binlog 可能会出现乱序,导致脏数据。所以我们还需要对现有的高可用进一步增强,要保障局部节点不可用时,不仅 Topic 可读可写,并且 Topic 的可读写队列数量不变,指定的队列也是可读可写的。

如下图,NameServer 或 Broker 任意出现单点不可用,Topic A 依然保持 2 个队列,每个队列都具备读写能力。

为了解决 MessageQueue 高可用的场景,RocketMQ 5.0 引入全新的高可用机制。我们先来了解其中的核心概念:

  • Dledger Controller,这是一个基于 raft 协议的强一致元数据组件,来执行选主命令、维护状态机信息。
  • SynStateSet,如图,它维护了处于同步状态的副本组集合,这个集合里的节点都有完整的数据,当主节点宕机后,就从这个集合中选择新的主节点。
  • Replication,用于不同副本之间的数据复制、数据校验、截断对齐等事项。

下图是 RocketMQ 5.0 HA 的架构全景图,这个高可用架构具有多个优势。

一是在消息存储引入了朝代和开始位点,基于这两个数据,完成数据校验、截断对齐,在构建副本组的过程中简化数据一致性逻辑。

二是基于 Dledger Controller,我们不需要引入 zk、etcd 等外部分布式一致性系统,并且 Dledger Controller 还可以和 NameServer 合并部署,简化运维、节约机器资源。

三是 RocketMQ 对 Dledger Controller 是弱依赖,即便 Dledger 整体不可用了,也只会影响选主,不影响正常的消息收发流程。

四是可定制,用户可以根据业务对数据可靠性、性能、成本综合选择,比如副本数可以是2、3、4、5,副本直接可以是同步复制、异步复制。如 2-2 模式表示,2 副本、并且数据同步复制;2-3 模式表示3副本,2副本多数派完成复制,才算成功。用户还可以将其中的一个副本部署在异地机房,异步复制实现容灾。

5.4. 云原生存储

前面我们讲的存储系统都是 RocketMQ 面向本地文件系统的实现。但是在云原生时代,当我们把 RocketMQ 部署到云环境,可以进一步利用云原生基础设施,如云存储来进一步增强 RocketMQ 的存储能力。在 RocketMQ 5.0 里面我们提供了多级存储的特性,它是内核级的存储扩展,我们面向对象存储扩展了对应的 Commitlog、ConsumeQueue 和 IndexFile;我们采用了插件化的设计,多级存储可以有多种实现,在阿里云上,我们基于 OSS 对象服务实现,在 AWS 上我们则可以面向 S3 的接口来实现。

通过引入了这个云原生的存储,RocketMQ 释放了很多红利:

  • 无限存储能力,消息存储空间不受本地磁盘空间的限制,原来是保存几天,现在可以几个月、甚至存一年。另外对象存储也是业界成本最低的存储系统,特别适合冷数据存储。
  • Topic 的 TTL,原来多个 Topic 的生命周期是和 Commitlog 绑定,统一的保留时间。现在每个 Topic 都会使用独立的对象存储 Commitlog 文件,可以有独立的 TTL。
  • 存储系统进一步的存算分离,能把存储吞吐量的弹性和存储空间的弹性分离。
  • 冷热数据隔离,分离了冷热数据的读链路,能大幅度提升冷读性能,不会影响在线业务。

相关文章:

深度剖析 RocketMQ 5.0 之架构解析:云原生架构如何支撑多元化场景?

拓展学习:🔍「RocketMQ 中文社区」 持续更新,提供 RocketMQ 领域专家模型的 AI 答疑 作者 | 隆基 简介: 了解 RocketMQ 5.0 的核心概念和架构概览;然后我们会从集群角度出发,从宏观视角学习 RocketMQ 的管…...

Spring中bean的生命周期(笔记)

bean的生命周期,按照最重要五步 第一步:实例化bean,调用无参构造方法(通过BeanDefinition利用反射实例化Bean对象(无参数构造方法) 并通过推断构造方法...并放入三级缓存中..) 第二步:给bean属性赋值(调用…...

transform-实现Encoder 编码器模块

Encoder 论文地址 https://arxiv.org/pdf/1706.03762 Encoder结构介绍 Transformer Encoder是Transformer模型的核心组件,负责对输入序列进行特征提取和语义编码。通过堆叠多层结构相同的编码层(Encoder Layer),每层包含自注意力机…...

LVGL -窗口操作

1 窗口背景介绍 在 LVGL 中,screen 是一个顶层对象,代表你设备上当前显示的整个画面。它相当于一个“全屏容器”,你可以在上面添加按钮、标签、图像、容器等各种界面控件。它的本质就是一个特殊的 lv_obj_t,但它没有父对象&#…...

ollama运行qwen3

环境 windows server GPU 32G 内存 40G 升级ollama 需要版本 0.6.6以上 ollama --version拉取模型 ollama pull qwen3:32b时间比较长,耐心等待 运行模型 ollama run qwen3:32b运行起来之后发现GPU是可以跑起来的,发个你好看看 默认是深度思考的,不…...

如何查看和验证AWS CloudFront的托管区域ID

在使用AWS Route 53设置DNS记录时,正确识别CloudFront分发的托管区域ID是至关重要的。本文将详细介绍几种查看和验证CloudFront托管区域ID的方法,特别关注中国区CloudFront的特殊情况。 为什么托管区域ID很重要? 托管区域ID是AWS服务中的一个关键标识符。在创建指向CloudF…...

yum 安装 ncurses-devel 报错 baseurl 的解决方法

解决 yum 安装 ncurses-devel 报错(baseurl 问题) 出现 yum install ncurses-devel 报错 Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64 的原因,很可能是因为 CentOS 7 的 SCL 源在 2024 年 6 月 30 日停止维护了。以下是解…...

《Vue3学习手记7》

组件通信&#xff08;续&#xff09; $attrs 组件通信&#xff1a;$attrs 适用于祖传孙或孙传祖 &#xff08;需要通过中间组件&#xff09; 传递给后代的数据&#xff0c;但未被接收&#xff0c;都保存在attrs中 1.祖传孙 父组件&#xff1a; <template><div cl…...

算法备案类型解析:如何判断你的算法属于哪种类型?

根据《互联网信息服务算法推荐管理规定》政策&#xff0c;算法备案已经成为了强制性备案。但对于企业而言&#xff0c;如何准确判断自身算法所属的备案类型往往存在困惑&#xff0c;今天我们就来详细盘一盘算法备案的类型&#xff0c;教你如何判断自己的算法属于哪一类 一、算…...

Javascript 中作用域的理解?

一、作用域的类型 1. 全局作用域&#xff08;公司大门外&#xff09; 范围&#xff1a;整个 JavaScript 文件变量&#xff1a;像贴在公告栏上的信息&#xff0c;所有人可见例子&#xff1a;const companyName "阿里"; // 全局变量&#xff0c;任何地方都能访问 fu…...

Qt入门——什么是Qt?

Qt背景介绍 什么是Qt? Qt 是⼀个 跨平台的 C 图形用户界面应用程序框架 。它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是 完全面向对象 的&#xff0c;很容易扩展。Qt 为开发者提供了 ⼀种基于组件的开发模式 &#xff0c;开发者可以通过简单的拖拽和组合…...

Snap7西门子PLC通信协议

S7协议&#xff0c;作为西门子的专有协议&#xff0c;广泛应用于多种通讯服务中&#xff0c;如PG通讯、OP通讯以及S7基本通讯等。它独立于西门子的各种通讯总线&#xff0c;能够在MP、PROFIBUS、Ethernet以及PROFINET等多种网络上运行。S7协议实质上是一个由多种应用层协议构成…...

GTC Taipei 2025 医疗域前瞻:从AI代理到医疗生态,解码医疗健康与生命科学的未来图景

引言 2025年,全球医疗健康领域正经历一场由人工智能、机器人技术与分布式计算驱动的范式转移。随着NVIDIA及其生态伙伴在GTC Taipei 2025大会上的深度布局,医疗行业的核心趋势愈发清晰:AI代理程序(Digital AI Agents)赋能临床协作、医疗大数据与精准医学加速落地、医学影…...

C++的vector中emplace_back() 与 push_back() 的区别

C 中 vector 的 emplace_back() 和 push_back() 均用于向容器末尾添加元素&#xff0c;但二者在实现和效率上有显著区别&#xff1a; 1. 参数传递方式 push_back()&#xff1a;接受一个已构造的对象&#xff08;左值或右值&#xff09;&#xff0c;将其拷贝或移动到容器中。 s…...

LangChain4j +DeepSeek大模型应用开发——5 持久化聊天记忆 Persistence

默认情况下&#xff0c;聊天记忆存储在内存中。如果需要持久化存储&#xff0c;可以实现一个自定义的聊天记忆存储类&#xff0c;以便将聊天消息存储在你选择的任何持久化存储介质中。 1. 存储介质的选择 大模型中聊天记忆的存储选择哪种数据库&#xff0c;需要综合考虑数据特…...

C++核心编程 1.2 程序运行后

1.2 程序运行后 栈区&#xff1a; 由编译器自动分配释放, 存放函数的参数值,局部变量等 注意事项&#xff1a;不要返回局部变量的地址&#xff0c;栈区开辟的数据由编译器自动释放 int * func() {int a 10;return &a; }int main() {int *p func();cout << *p <…...

小市值策略复现(A股选股框架回测系统)

相关config配置 https://quantkt.com/forumDetail?id201043 很早就知道了小市值模型&#xff0c;正好量化选股回测框架出来了&#xff0c;把最裸的小市值复现下&#xff0c;顺便验证下框架逻辑。 科普: 小市值策略基于 “小市值效应”&#xff0c;即从历史数据来看&#xf…...

C语言(6)—函数递归

文章目录 一、递归的基本概念1.1 什么是递归1.2 递归的核心思想1.3 递归的必要条件 二、递归的经典应用2.1 阶乘计算 三、递归与迭代的比较3.1 递归的优缺点3.2 迭代的优缺点 四、递归的底层机制4.1 函数调用栈4.2 栈溢出风险 五、递归优化技巧5.1 记忆化&#xff08;Memoizati…...

【网络】HTTP报文首部字段

目录 一. 预备知识 1.1.代理、网关和隧道 1.1.1.代理 1.1.2.网关 1.1.3.隧道 1.2.保存资源的缓存 1.2.1.缓存的有效期限 1.2.2.客户端的缓存 1.3.用单台虚拟主机实现多个域名 二. HTTP首部字段 2.1.HTTP 首部字段格式 2.2.四种 HTTP 首部字段类型 三. HTTP通用首部…...

【Fifty Project - D20】

今日完成记录 TimePlan完成情况7&#xff1a;30 - 11&#xff1a;30收拾行李闪现广州 & 《挪威的森林》√10&#xff1a;00 - 11&#xff1a;00Leetcode√16&#xff1a;00 - 17&#xff1a;00健身√ Leetcode 每日一题 每日一题来到了滑动窗口系列&#xff0c;今天是越…...

【Linux系统】systemV共享内存

system V共享内存 在Linux系统中&#xff0c;共享内存是一种高效的进程间通信&#xff08;IPC&#xff09;机制&#xff0c;它允许两个或者多个进程共享同一块物理内存区域&#xff0c;这些进程可以将这块区域映射到自己的虚拟地址空间中。 共享内存区是最快的IPC形式。一旦这…...

【计算机网络】DHCP——动态配置ip地址

DHCP 是什么&#xff1f; DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09; 是一种网络协议&#xff0c;用于自动分配 IP 地址和其他网络配置参数&#xff08;如子网掩码、默认网关、DNS 服务器等&#xff09;给网络中的设备&…...

TDengine 订阅不到数据问题排查

简介 TDengine 在实际生产应用中&#xff0c;经常会遇到订阅程序订阅不到数据的问题&#xff0c;总结大部分都为使用不当或状态不正确等问题&#xff0c;需手工解决。 查看服务端状态 通过 sql 命令查看有问题的 topic 和consumer_group 组订阅是否正常。 select * from inf…...

低版的spring boot 1.X接入knife4j

低版的spring boot 1.X接入knife4j 老的项目是用spring boot 1.5.10.RELEASE 不好升级 &#xff0c;原来接口文档一直用的是老的swagger样式&#xff0c;不是很好看&#xff0c;网上查了下&#xff0c;发现有个knife4j挺好看的&#xff0c;用一下他们的样式&#xff0c;下面是…...

outlook for mac本地邮件存放在哪儿?

尽管 PST 格式通常与 Microsoft Outlook 联系在一起&#xff0c;但认为它也在 Mac OS 上存储邮箱数据是一种误解。实际上&#xff0c;Outlook for Mac 不会将邮件存储为 PST 文件。无法在 Outlook for Mac 中找到 PST 文件位置&#xff0c;因为它不使用 PST 文件来存储邮箱数据…...

javascript<——>进阶

一、作用域&#xff1a;变量可以被访问的范围 1.局部作用域 1.1函数作用域 在函数内部声明的变量&#xff0c;在函数内部被访问的&#xff0c;外部无法直接访问。 总结&#xff1a;1、函数内部声明的变量&#xff0c;在函数外部无法直接访问 2、函数的参数也是函数内部的局…...

Java练习8

一.题目 二.源码 package TestRuMen;import java.util.Random; import java.util.Scanner;public class Test11 {public static void main(String[] args){// 调用 createNumber 方法生成一组随机的中奖号码int[] arrcreateNumber();// 调用 userInputNumber 方法获取用户输入…...

C语言按位操作符

在C语言中&#xff0c;按位操作符直接对整数的二进制位&#xff08;bit&#xff09;进行操作&#xff0c;常用于底层编程、硬件控制或性能优化场景。以下是按位操作符的详细说明和用法&#xff1a; 1. 按位操作符列表 操作符名称功能描述示例&按位与对应位均为1时结果为1&…...

Linux(权限管理)

权限概述 基本概念 定义&#xff1a;Linux权限是操作系统对用户和进程访问资源进行精细化管控&#xff0c;通过读&#xff08;r4&#xff09;、写&#xff08;w2&#xff09;、执行&#xff08;x1&#xff09;三种基础权限组合实现。 其中在运维的角度看它们所对应的操作权限…...

Redis入门到实战——基础篇

一、初识Redis 1. 认识NoSQL 2. 认识Redis Redis诞生于2009年&#xff0c;全称Remote Dictionary Server&#xff0c;远程词典服务器&#xff0c;是一个基于内存的键值型NoSQL数据库。 特征&#xff1a; 键值型&#xff08;key-value&#xff09;&#xff0c;value支持多种…...

ctf.show 卷王杯 pwn签到

pwn签到 64位 ret2libc pwn签到 (1) motalymotaly-VMware-Virtual-Platform:~/桌面$ file pwn pwn: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]0953abcf1dd6…...

Dali 1.1.4 | 使用尖端技术将描述转换成独特艺术品、照片和图像,发挥无限创意

Dali是一款先进的AI图像生成器应用程序&#xff0c;能够根据用户的描述生成不同风格的独特图像。无论是迷人的数字艺术、创新的纹身设计还是独一无二的标志&#xff0c;甚至是超写实的照片&#xff0c;Dali都能轻松应对。这款解锁版为用户提供了更多的创作自由度和无限可能&…...

LeetCode 2906 统计最大元素出现至少K次的子数组(滑动窗口)

给出一个示例&#xff1a; 输入&#xff1a;nums [1,3,2,3,3], k 2 输出&#xff1a;6 解释&#xff1a;包含元素 3 至少 2 次的子数组为&#xff1a;[1,3,2,3]、[1,3,2,3,3]、[3,2,3]、[3,2,3,3]、[2,3,3] 和 [3,3] 。该题也是一个比较简单的滑动窗口的题目&#xff0c;但是…...

文献阅读(三)基于干旱强度和恢复时间的生态系统恢复力评估|《Agricultural and Forest Meteorology》

傅伯杰院士团队发表在《Agricultural and Forest Meteorology》上的一篇文章&#xff0c;定义了一个新的恢复力指标&#xff0c;通过指数拟合曲线表征干旱强度和相应恢复时间的关系&#xff0c;用曲线面积量化恢复力&#xff1b;耦合干旱强度和恢复时间来评估生态系统对干旱的恢…...

32、Server.Transfer和Response.Redirect的区别是什么?

Server.Transfer 和 Response.Redirect 是 ASP.NET 中用于页面跳转的两种方法&#xff0c;但它们在实现机制、性能、URL 显示等方面存在显著区别。以下是两者的核心差异&#xff1a; 1. 实现机制 Server.Transfer 服务器端跳转&#xff1a;直接在服务器内部将请求从当前页面…...

iOS—仿tableView自定义闹钟列表

自定义View实现闹钟列表&#xff0c;左滑删除&#xff0c;滑动列表时收起删除按钮。用代理的方法实现ListView的创建&#xff0c;删除以及开关回调&#xff0c;并实现动画效果。 ClockViewCell使用block通知ListView&#xff0c;ListView通过代理通知上层ClockView 1、文件组…...

Spark,集群搭建-Standalone

集群搭建-Standalone 一、解压 在之前的学习中我们有了一个软件包 spark.3.1.2-bin-hadoop3.2.tgz &#xff08;eg我的在 /opt/software目录下&#xff09;把这个软件包解压到 /opt/module 下&#xff08;也可以自己决定解压到哪里&#xff09;。对应的命令是&#xff1a; t…...

【C++11】新的类功能、lambda

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲C11——新的类功能、lambda、包装器 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C学习笔记 &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&#xff1a;C语言入门基础&#xf…...

stm32 g031g8 flash擦除函数被坑

先记录一下在擦除的时候由于调用了这个FLASH_PageErase(FLASH_BANK_1, secpos); 导致擦除不成功&#xff0c;写入失败。 下面的擦除有问题// 使用 FLASH_PageErase 擦除该页while ((FLASH->SR & FLASH_SR_BSY1) ! 0); // 等待空闲FLASH_PageErase(FLASH_BANK_1, secpo…...

SQL实战:04之SQL中的分组问题求解

文章目录 概述题目&#xff1a;分组问题求解题解第一步&#xff1a;求解差值步骤二&#xff1a;窗口分组累加完整SQL 总结 概述 最近刷题时遇到一些比较有意思的题目&#xff0c;乍一遇上时还不知道怎么求解&#xff0c;在灵光一闪时找到了问题的求解答案&#xff0c;感觉还比…...

基于DrissionPage的实习信息爬虫改造与解析

目录 ​编辑 一、DrissionPage技术优势分析 二、代码改造实现 2.1 环境配置 2.2 爬虫类定义 2.3 核心爬取逻辑 一级页面解析优化 二级页面解析优化 2.4 分页控制机制 三、关键技术解析 3.1 智能元素定位 3.2 请求管理优化 3.3 反爬对抗策略 四、改造前后对比测试…...

react-native打包报错:缺少build文件夹

在React Native项目中&#xff0c;如果你遇到了提示“没有build文件夹”的问题&#xff0c;这通常是因为项目的某些部分没有正确初始化或者配置。以下是一些解决步骤。如果缺少build文件&#xff0c;这会导致你使用gradlew assembleRealease失败&#xff0c;进而无法打包APK。下…...

【无需安装额外软件,JavaScript脚本】B站批量取消关注

步骤 注意&#xff1a; 提前选好需要批量取消关注的分组&#xff01;&#xff01;&#xff01;脚本过程中会提示要求输入B站账号的手机号码作为验证&#xff0c;不是封号&#xff0c;只是验证&#xff01;&#xff01;&#xff01; 打开B站关注页面 进入个人关注网页&#xff0…...

【Linux】第十五章 调度未来任务

1.如何调度延迟的用户任务&#xff1f; at 软件包包含 atd守护进程&#xff0c;和一组命令&#xff08;at、atq等&#xff09;。在默认的 RHEL 安装过程中&#xff0c;将自动安装并启用 atd守护进程。root 及普通用户可以使用 at 命令创建计划任务&#xff0c;atd守护进程提供…...

JVM GC垃圾回收算法

垃圾回收算法&#xff08;GC Algorithms&#xff09; JVM 根据对象生命周期特性&#xff08;分代假设&#xff09;采用不同的回收算法&#xff0c;核心算法包括&#xff1a; 标记-清除&#xff08;Mark-Sweep&#xff09; 此算法执行分两阶段。第一阶段从引用根节点开始标记…...

计算机毕业设计--基于深度学习(U-Net与多尺度ViT)的车牌模糊图像修复算法设计与实现(含Github代码+Web端在线体验界面)

基于深度学习的U-Net架构下多尺度Transformer车牌图像去模糊算法设计与实现 如果想对旧照片进行模糊去除&#xff0c;划痕修复、清晰化&#xff0c;请参考这篇CSDN作品&#x1f447; 计算机毕业设计–基于深度学习的图像修复&#xff08;清晰化划痕修复色彩增强&#xff09;算…...

塑料材料工程师简历模板

模板信息 简历范文名称&#xff1a;塑料材料工程师简历模板&#xff0c;所属行业&#xff1a;其他 | 职位&#xff0c;模板编号&#xff1a;DEEBPX 专业的个人简历模板&#xff0c;逻辑清晰&#xff0c;排版简洁美观&#xff0c;让你的个人简历显得更专业&#xff0c;找到好工…...

Nginx核心功能与LNMP部署

目录 一、引言 二、Nginx 简介 2.1 Nginx 的起源与发展 2.2 Nginx 的特点 三、Nginx 核心功能详解 3.1 HTTP 服务器功能 3.1.1 静态资源处理 3.1.2 HTTP 协议支持 3.2 反向代理功能 3.2.1 反向代理的原理 3.2.2 Nginx 反向代理配置 3.3 负载均衡功能 3.3.1 负载均…...

爬虫学习笔记(五)---数据解析之re

数据提取 前面的爬虫笔记学习的都是如何爬取整个页面的内容&#xff0c;服务器渲染中&#xff0c;数据是直接放在源代码html里面的&#xff0c;大多数情况下整个页面的内容真正需要的只是一小部分&#xff0c;那把这一小部分提取出来的过程就叫做数据提取 数据解析方式 re解…...

ESP32- 开发笔记- 软件开发 4 - GPIO 口

1 背景介绍 GPIO&#xff08;General Purpose Input/Output&#xff09; ——通用输入输出口&#xff0c;就是能由软件自由控制输入&#xff08;接收外界信号&#xff09;或输出&#xff08;发出电平信号&#xff09;的引脚。 ESP32 最核心的功能之一&#xff0c;能被用来控制…...