消息队列:原理、问题与设计全解析
1.如何保证消息的顺序性
保证消息顺序性通常是在分布式系统或网络通信中遇到的一个挑战。以下是几种常见的方法来确保消息的顺序性:
-
单生产者单消费者模型:
- 如果系统设计为只有一个生产者和一个消费者,那么保持消息顺序相对简单,因为所有消息都通过同一个通道按序传递。
-
全局时钟或时间戳:
- 给每条消息附加一个由全局时钟生成的时间戳。接收端可以根据时间戳对消息进行排序。然而,这种方法在分布式环境中可能不太实际,因为很难维持一个精确同步的全局时钟。
-
序列号:
- 每个消息附带一个递增的序列号。发送方负责分配唯一的序列号,而接收方则根据序列号对消息排序。这是实现有序交付的一种常见方法。
-
分区(Partitioning)与键(Key):
- 在一些消息队列系统中(如Kafka),可以通过指定消息键(key)将相关联的消息路由到相同的分区。这样可以确保同一键下的消息按照发送顺序被处理。
-
FIFO队列:
- 使用先进先出(FIFO)原则的消息队列服务(例如Amazon SQS FIFO队列)。这类队列保证了消息的顺序性和唯一性,即使在网络故障或系统崩溃后也能恢复消息的顺序。
-
事务日志:
- 在某些数据库系统中,使用事务日志记录所有的更改操作,确保数据更新的顺序性。类似的概念也可以应用于消息系统中。
-
两阶段提交协议(Two-Phase Commit Protocol, 2PC):
- 虽然主要用于保证分布式事务的一致性,但在某些情况下也可用于确保消息传递的顺序性。
-
幂等性:
- 设计消息处理逻辑以支持幂等性,即相同的消息可以被安全地处理多次而不影响最终结果。这有助于在需要重试机制的情况下保持消息的顺序。
-
阻塞发送:
- 发送方在发送下一条消息之前等待确认上一条消息已被成功接收。虽然这种方法能确保顺序,但它可能会降低系统的吞吐量。
选择哪种方法取决于具体的用例、性能要求以及系统的复杂程度。在实际应用中,这些策略可能需要组合使用以达到最佳效果。
2.如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
针对消息队列的延时、过期失效问题以及队列满后的处理,这里有一些策略和建议:
解决消息队列延时及过期失效问题
-
设置消息TTL(Time To Live):
- 消息队列服务通常允许为每条消息设置一个存活时间(TTL)。一旦消息超过了这个时间而未被消费,它将被视为过期,并从队列中移除或转移到死信队列。
-
监控与报警:
- 实施监控机制来跟踪消息队列的性能指标,如平均延时、最大延时等。当检测到异常情况时,及时发出警报以便采取行动。
-
优化消费者处理速度:
- 确保消费者端有足够的资源来快速处理消息。可以通过增加消费者实例的数量或者优化单个消费者的处理逻辑来提高吞吐量。
-
优先级队列:
- 如果某些类型的消息需要更快地得到处理,可以考虑使用优先级队列,让高优先级的消息先被消费。
-
异步处理与批量处理:
- 对于一些非实时要求的任务,可以采用异步处理的方式;对于大批量的小型任务,尝试合并成较大的批次进行一次性处理以减少延迟。
-
调整网络配置:
- 优化网络连接参数,比如TCP窗口大小、拥塞控制算法等,有助于减少网络传输造成的延迟。
处理消息队列满了的情况
-
扩展队列容量:
- 增加存储空间或使用分布式消息队列系统,使得队列能够容纳更多的消息。
-
限流与拒绝策略:
- 当队列接近满载时,实施限流措施限制新消息的进入,或者直接拒绝新的消息直到现有消息被适当处理。
-
水平扩展消费者:
- 增加更多消费者节点并行工作,加快消息的消耗速度。
-
重试机制与死信队列:
- 对于暂时无法处理的消息,不要立刻丢弃它们,而是放入死信队列等待后续处理。同时,设计合理的重试逻辑避免无限循环重试。
应对几百万消息积压的问题
-
紧急扩容:
- 快速部署额外的消费者实例来加速消息处理过程。云服务提供商通常支持自动扩展功能,可以根据负载动态调整资源。
-
分流处理:
- 将积压的消息根据一定规则分配给不同的处理组或子队列,从而分散压力。
-
数据压缩与清理:
- 对旧的或不再重要的消息进行压缩存储甚至删除,减轻队列负担。
-
分析根因并修复:
- 分析导致积压的根本原因,可能是上游系统的突发流量、下游服务的故障或其他因素。针对发现的问题做出相应调整,防止未来再次发生类似状况。
-
预读取与预处理:
- 在可能的情况下,提前读取消息并做一些简单的预处理工作,例如验证格式、过滤无效项等,这样可以减少实际处理阶段的工作量。
通过上述方法的组合应用,可以有效地解决消息队列中的延时、过期失效问题以及应对大量消息积压的情形。重要的是要持续监控系统状态,并根据实际情况灵活调整策略。
3.让你来设计一个消息队列,你会怎么设计
设计一个高效、可靠的消息队列系统需要综合考虑多个方面,包括但不限于性能、可靠性、可扩展性、持久性和易用性。下面我将从这些角度出发,描述一个消息队列系统的设计思路。
1. 系统架构
分布式架构
- 节点角色划分:设计为主节点(Master)和工作节点(Worker),主节点负责管理集群状态、分配任务等;工作节点实际执行消息的存储与转发。
- 高可用性:采用主备复制机制,确保即使主节点故障也有备用节点可以接管服务。
- 水平扩展:支持通过增加工作节点来线性提升系统的处理能力和存储容量。
数据分区与副本
- 数据分区(Partitioning):为了提高并发度和吞吐量,对消息流进行分区,每个分区可以独立地被不同消费者组消费。
- 多副本机制:为关键数据设置多个副本,以增强数据冗余度和读取性能,并防止单点故障。
2. 消息模型
生产者-消费者模式
- 支持发布/订阅模式,允许一个或多个生产者向主题(Topic)发送消息,同时允许多个消费者订阅同一个主题并接收消息。
消息持久化
- 提供两种级别的持久化选项:内存中快速缓存(适用于低延迟场景)以及磁盘上的持久化存储(保证数据不会因系统崩溃而丢失)。
消息确认机制
- 实现ACK机制,确保每条消息都被正确消费后才从队列中移除。对于失败的消息,提供重试逻辑或转移到死信队列(DLQ)。
3. 性能优化
预加载与批量处理
- 允许生产者预先批量提交消息到本地缓存,减少网络交互次数;同时,消费者也可以批量拉取消息,提高处理效率。
异步IO与非阻塞算法
- 利用异步IO操作和非阻塞算法,如Netty框架,最大化资源利用率,特别是在高并发环境下。
4. 可靠性保障
消息TTL(Time To Live)
- 设置消息存活时间,超过此期限未被消费的消息将自动失效,避免无限期占用资源。
限流与熔断
- 实施流量控制策略,限制单位时间内进入系统的请求数量,保护系统免受突发流量冲击;当检测到异常时触发熔断机制,暂时停止部分服务直到恢复正常。
5. 安全性
身份验证与授权
- 通过OAuth2.0、JWT等方式实现用户身份验证,并基于角色的访问控制(RBAC)授予不同的权限级别。
加密传输
- 使用TLS/SSL加密所有网络通信,确保消息在传输过程中不被窃听或篡改。
6. 监控与运维
健康检查与自动恢复
- 设计健康检查接口,定期探测各组件的状态,一旦发现问题立即尝试自我修复或者通知管理员介入。
日志记录与报警
- 记录详细的日志信息,便于故障排查;设置阈值监控关键指标,如CPU使用率、内存占用、消息积压情况等,当达到设定条件时发出警告。
7. 用户体验
API设计
- 提供RESTful API或SDK,简化开发人员集成过程,降低学习成本。
文档与社区支持
- 编写详尽的技术文档,包括安装指南、配置说明、最佳实践案例等;建立活跃的社区论坛,鼓励用户交流经验和解决问题。
以上是关于如何设计一个消息队列系统的高层次概述。具体实现细节会根据所选技术栈和技术要求有所不同。此外,随着业务需求的变化和技术的发展,设计方案也需要持续迭代和完善。
相关文章:
消息队列:原理、问题与设计全解析
1.如何保证消息的顺序性 保证消息顺序性通常是在分布式系统或网络通信中遇到的一个挑战。以下是几种常见的方法来确保消息的顺序性: 单生产者单消费者模型: 如果系统设计为只有一个生产者和一个消费者,那么保持消息顺序相对简单,…...
成功!QT 5.15.2编译mysql驱动
首选要说明,5.15与6.7编译驱动是完全不同的。搞错了永远编译不出来。 参考 主要是参考安装QT,安装mysql等。 编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MSVC版)_mingw编译qt6.7-CSDN博客 复制mysql的include和lib到一个方便的目…...
【玩转全栈】----Django连接MySQL
阅前先赞,养好习惯! 目录 1、ORM框架介绍 选择建议 2、安装mysqlclient 3、创建数据库 4、修改settings,连接数据库 5、对数据库进行操作 创建表 删除表 添加数据 删除数据 修改(更新)数据: 获取数据 1、OR…...
【Spring Boot】Spring AOP 快速上手指南:开启面向切面编程新旅程
前言 🌟🌟本期讲解关于spring aop的入门介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不…...
力扣--54.螺旋矩阵
题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 提示: m matrix.length n matrix[i].length 1 < m, n < 10 -100 < matrix[i][j] < 100代码 class Solution { public List spiralOr…...
【Uniapp-Vue3】image媒体组件属性
如果我们想要在页面上展示图片就需要使用到image标签。 这部分最重要的是图片的裁剪,图片的裁剪和缩放属性: mode 图片裁剪、缩放的模式 默认值是scaleToFill 我将用两张图片对属性进行演示,一张是pic1.jpg(宽更长…...
Ubuntu上安装Apache Spark
在Ubuntu上安装Apache Spark的步骤如下: 1. 安装Java Spark是用Scala编写的,并且依赖Java。因此,首先需要安装Java。 安装OpenJDK 8(或更高版本) 执行以下命令安装OpenJDK: sudo apt update sudo apt …...
Nginx入门笔记
Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx(1). 安装必要的依赖(2)下载nginx(3)编译安装(4)编译并安装 Nginx(5)启动nginx …...
HTML5 滑动效果(Slide In/Out)详解
HTML5 滑动效果(Slide In/Out)详解 滑动效果(Slide In/Out)是一种常见的动画效果,使元素从一侧滑入或滑出,增强页面的动态感和用户体验。以下是滑动效果的详细介绍及实现示例。 1. 滑动效果的特点 动态视…...
unity学习8:unity的基础操作 和对应shortcut
目录 1 unity的基础操作的工具,就在scene边上 1.1 对应shortcut快捷键 2 物体的重置/ 坐标归到0附近 3 F:快速找到当前gameobject 4 Q:小手和眼睛,在场景中移动 5 W:十字箭头,移动gameobject 6 …...
计算机网络 (32)用户数据报协议UDP
前言 用户数据报协议(UDP,User Datagram Protocol)是计算机网络中的一种重要传输层协议,它提供了无连接的、不可靠的、面向报文的通信服务。 一、基本概念 UDP协议位于传输层,介于应用层和网络层之间。它不像TCP那样提…...
java内存区域 - 栈
目录 java内存区域 - 栈1. Java虚拟机栈的组成2. 栈帧中的详细内容2.1 局部变量表2.2 操作数栈2.3 动态链接2.4 方法返回地址2.5 附加信息 3. JVM栈的生命周期4. 示例解析 - 运行时的栈帧分布5. 栈中的异常6.栈配置7.本地方法栈 java内存区域 - 栈 在JDK11中,JVM栈…...
AI大模型-提示工程学习笔记5
卷首语:我所知的是我自己非常无知,所以我要不断学习。 写给AI入行比较晚的小白们(比如我自己)看的,大神可以直接路过无视了。 零提示是什么 “零提示”(Zero-shot)是指在没有提供任何特定示例…...
跨站脚本攻击(XSS)详解
跨站脚本攻击(XSS)详解 跨站脚本攻击(XSS,Cross-Site Scripting)是一种通过在网页中注入恶意脚本,攻击用户浏览器的漏洞。攻击者可以利用XSS窃取用户敏感信息、劫持会话、或在受害者浏览器中执行恶意操作。…...
【图像加密解密】Logistic混沌映射的彩色图像加密算法复现(含相关性检验)【Matlab完整源码 1期】
1、说明 本文给出详细完整代码、完整的实验报告和PPT。 环境:MATLAB2019a 复现文献:[1]黄硕.基于改进的Logistic混沌映射彩色图像加密算法[J].河南工程学院学报(自然科学版),2015,27(02):63-67. 主要目的是为了快速了解何为混沌序列、混沌序列产生、…...
VUE学习
import { ref } from vue; 引入了 Vue 的 ref 函数,用于创建响应式数据。const message ref(Hello Vue3); 创建了一个响应式变量 message 并初始化为字符串 Hello Vue3。<h1>{{ message }}</h1> 使用了 Vue 的插值表达式 {{ message }} 来显示 message…...
buildroot 编译 x264 及 ffmpeg
buildroot 编译 x264 及 ffmpeg 依赖安装x264编译安装解压源码并修改配置文件配置及编译编译错误: aarch64-linux-ar: two different operation options specified编译结果ffmpeg安装源码编译错误 : ERROR: x264 not found using pkg-config为在rk3568平台上开发音视频采集及…...
HarmonyOS开发:ArkTS初识
ArkTS基本语法 ArkTS语言简介 ArkTS是鸿蒙生态的应用开发语言。基本语法风格与TypeScript(简称TS)相似,在TS的生态基础上进一步扩展,继承了TS的所有特性,是TS的超集。 基本语法概述 扩展能力 基础语法:…...
C++ STL map和set的使用
序列式容器和关联式容器 想必大家已经接触过一些容器如:list,vector,deque,array,forward_list,string等,这些容器统称为系列容器。因为逻辑结构为线性的,两个位置的存储的值一般是…...
VisionPro软件Image Stitch拼接算法
2D图像拼接的3种情景 1.一只相机取像位置固定,或者多只相机固定位置拍图,硬拷贝拼图,采用CopyRegion工具实现 2.一只或多只相机在多个位置拍照,相机视野互相重叠,基于Patmax特征定位后,无缝 拼图ÿ…...
缓存-Redis-缓存更新策略-主动更新策略-Cache Aside Pattern(全面 易理解)
**Cache-Aside Pattern(旁路缓存模式)**是一种广泛应用于缓存管理的设计模式,尤其在使用 Redis 作为缓存层时尤为常见。该模式通过在应用程序与缓存之间引入一个旁路,确保数据的一致性和高效性。本文将在之前讨论的 Redis 主动更新…...
Linux(Centos 7.6)命令详解:cd
1.命令作用 改变当前工作目录(change directory) 2.命令语法 Usage: cd [-L|[-P [-e]]] [dir] 3.参数详解 -L,当目标路径是符号链接时,强制使用符号链接,这是一个默认选项。-P,使用物理路径代替符号链接。-e࿰…...
oracle位运算、左移右移、标签算法等
文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用,废弃掉该方案)右移函数(略,有此场景吗?) 实际应用资质字典…...
预训练语言模型——BERT
1.预训练思想 有了预训练就相当于模型在培养大学生做任务,不然模型初始化再做任务就像培养小学生 当前数据层面的瓶颈是能用于预训练的语料快被用完了 现在有一个重要方向是让机器自己来生成数据并做微调 1.1 预训练(Pre - training)vs. 传…...
基于Thinkphp6+uniapp的陪玩陪聊软件开发方案分析
使用uni-app框架进行前端开发。uni-app是一个使用Vue.js开发所有前端应用的框架,支持一次编写,多端发布,包括APP、小程序、H5等。 使用Thinkphp6框架进行后端开发。Thinkphp6是一个轻量级、高性能、面向对象的PHP开发框架,具有易…...
C++异常处理
C异常处理 C中的异常处理机制是通过try、throw和catch三个关键字来实现的,主要用于捕获和处理程序执行过程中可能出现的错误或异常情况,从而提高程序的健壮性和可维护性。 基本概念 try块:用于定义一个可能抛出异常的代码块。在这个代码块…...
UVM: TLM机制
topic overview 不建议的方法:假如没有TLM TLM TLM 1.0 整个TLM机制下,底层逻辑离不开动作发起者和被动接受者这个底层的模型基础,但实际上,在验证环境中,任何一个组件,都有可能成为动作的发起者࿰…...
基于机器学习的故障诊断(入门向)
一、原始信号的特征提取 1.EMD经验模态分解的作用 信号分析:EMD可以将信号分解为多个IMFs,每个IMF代表信号中的一个特定频率和幅度调制的成分。这使得EMD能够提供对信号的时频特征进行分析的能力(特征提取用到的)。信号去噪&…...
Linux 磁盘管理命令:使用xfs 管理命令
文章目录 Linux磁盘管理命令使用xfs 管理命令1.命令说明2.建立 XFS 文件系统4.调整 XFS 文件系统各项参数5.在线调整 XFS 文件系统的大小6.暂停和恢复 XFS 文件系统7.尝试修复受损的 XFS 文件系统8.备份和恢…...
《Spring Framework实战》8:4.1.3.Bean 概述
欢迎观看《Spring Framework实战》视频教程 Spring IoC 容器管理一个或多个 bean。这些 bean 是使用 您提供给容器的配置元数据(例如,以 XML <bean/>定义的形式)。 在容器本身中,这些 bean 定义表示为BeanDefinition对象&a…...
Spring Boot教程之五十二:CrudRepository 和 JpaRepository 之间的区别
Spring Boot – CrudRepository 和 JpaRepository 之间的区别 Spring Boot建立在 Spring 之上,包含 Spring 的所有功能。由于其快速的生产就绪环境,使开发人员能够直接专注于逻辑,而不必费力配置和设置,因此如今它正成为开发人员…...
MyBatis面试-1
1、什么是MyBatis? MyBatis是一个半ORM框架(对象关系映射)。---》Hibernate全ORM框架 ---》基于JDBC封装的框架 专注于SQL语句,不用关心JDBC操作的其他流程 2、MyBatis有什么优点 基于SQL语句的编程,相对来说会更加的灵活和JDBC相比&#…...
GDPU Android移动应用 重点习题集
目录 程序填空 ppt摘选 题目摘选 “就这两页ppt,你还背不了吗” “。。。” 打开ppt后 “Sorry咯,还真背不了😜” 程序填空 网上摘选的大题也挺合适的,太难的帮大家过滤掉了,大家可以看一下。 ✨SharedPrefere…...
软件开发为什么要用CI/CD方法
现代化业务离不开应用。事实上,62% 的企业认为,应用对其业务至关重要,还有 36% 的企业认为,通过应用提升了竞争优势2。快速可靠的应用开发是在数字世界取得成功的关键。持续集成/持续部署(CI/ CD)方法可帮助…...
湘潭大学人机交互复习
老师没给题型也没划重点,随便看看复习了 什么是人机交互 人机交互(Human-Computer Interaction,HCI)是关于设计、评价和实现供人们使用的交互式计算机系统,并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …...
Java高频面试之SE-10
hello啊,各位观众姥爷们!!!本牛马baby今天又来了!哈哈哈哈哈嗝🐶 equals和 的区别? 在 Java 中,equals() 方法和 运算符都是用于比较两个对象之间的相等性,但它们的工…...
Java 注解详解:RetentionPolicy 与 ElementType
文章目录 1. RetentionPolicy:注解的生命周期RetentionPolicy 的详细说明SOURCE 示例CLASS 示例RUNTIME 示例 2. ElementType:注解的应用范围ElementType 的详细说明ElementType 示例用于类用于方法用于局部变量 3. RetentionPolicy 与 ElementType 的结…...
javafx 将项目打包为 Windows 的可执行文件exe
要将 JavaFX 项目打包为 .exe 文件,你可以使用一些工具将你的应用程序封装为 Windows 可执行文件。以下是两种常用的方法: 方法 1:使用 jpackage(适用于 JDK 14 及更高版本) jpackage 是 JDK 内置的工具,…...
使用Chrome谷歌浏览器中内置翻译功能
谷歌Chrome浏览器作为全球最受欢迎的网络浏览器之一,提供了强大且便捷的内置翻译功能。这一功能帮助用户轻松跨越语言障碍,浏览试听包括音乐视频直播等网页内容了。 一、启用Chrome内置翻译功能 1、打开谷歌Chrome浏览器:确保你已经安装了最…...
Clojure语言的数据库编程
Clojure语言的数据库编程 引言 在当今社会,数据的处理和管理已经成为一个不可或缺的部分。无论是互联网应用、企业系统还是移动应用,都需要与数据库进行频繁的交互。因此,选择一种合适的编程语言和相应的库来进行数据库编程显得尤为重要。C…...
从零开始:使用VSCode搭建Python数据科学开发环境
引言 在数据科学领域,一个高效、稳定的开发环境是成功的关键。本文将详细介绍如何使用Visual Studio Code搭建一个完整的Python数据科学开发环境。通过本指南,您将学会: 安装和配置VSCode,包括基本设置和快捷键配置设置Python开…...
docker minio镜像arm64架构
minio版本为RELEASE.2021-09-03T03-56-13Z 原项目信创改造,服务器资源改为了arm64架构,统信uos docker镜像库内没有对应的minio镜像,当前镜像为拉取源码后,自编译打包镜像,亲测可用。 使用方式 将tar包导入到服务器…...
arcgisPro加载CGCS2000天地图后,如何转成米单位
1、导入加载的天地图影像服务,一开始是经纬度显示的。 2、右键地图,选择需要调整的投影坐标,这里选择坐标如下: 3、点击确定后,就可以调整成米单位的了。 4、切换后结果如下: 如有需要,可调整成…...
MySQL Binlog 监听方案
如果 EmbeddedEngine 类在 debezium-connector-mysql 中不可用,原因是 Debezium 的新版本移除了 EmbeddedEngine。这是因为 Debezium 的架构变更,它现在鼓励使用 Kafka Connect 或 Debezium Server 来处理数据变更事件。 下面是几种替代方法来实现 MySQ…...
openai swarm agent框架源码详解及应用案例实战
文章目录 简介数据类型Agent类Response类Result类Swarm类run_demo_loop交互式会话 基础应用agent-handsofffunction-callingcontext_variablestriage_agent 高阶应用通用客服机器人(support bot)构建航班服务agent 参考资料 openai 在24年10月份开源了一个教育性质的多agents协…...
Qt 5.14.2 学习记录 —— 팔 QWidget 常用控件(3)
文章目录 1、cursor2、font3、toolTip4、focusPolicy5、styleSheet 1、cursor 改变鼠标光标形状。 在Qt Designer界面中,拖一个按钮过来,右边属性面用户可以自己改cursor属性。 代码方法,先拖一个按钮到界面上: #include <Q…...
Nginx (40分钟学会,快速入门)
目录 一、什么是Nginx ? 可以做什么 ? 二、正向代理和反向代理 三、负载均衡 四、动静分离 五、Nginx 常用命令 六、Nginx实战及总结 一、什么是Nginx ? 可以做什么 ? Nginx 是高性能的 HTTP 和反向代理的 web 服务器,…...
C# 中await和async的用法(一)
在 C# 中,await 关键字用于异步编程,配合 async 方法一起使用。await 允许你等待异步操作完成,而不会阻塞当前线程。简而言之,await 会暂停当前方法的执行,直到任务完成,然后继续执行。 1. await与async的关…...
前端JS中var、let、const之间的区别
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 一、var 二、let 三、const 四、区别 变量…...
【pyqt】(八)ui文件使用
ui文件使用 前面我们已经学过了简单的UI文件创建(利用Qt Designer)和基础控件的使用。现在我们学习如何把二者融合起来完成开发。UI文件以 XML 格式存储界面的布局和各种控件的属性,我们可以利用Qt Designer开发界面,然后利用代码…...