惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
IT之家
IT之家
T
The Blog of Author Tim Ferriss
V
V2EX
博客园 - 聂微东
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
U
Unit 42
Vercel News
Vercel News
L
LangChain Blog
博客园 - 司徒正美
H
Help Net Security
Recent Announcements
Recent Announcements
Recorded Future
Recorded Future
V
Visual Studio Blog
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
Y
Y Combinator Blog
C
Check Point Blog
博客园 - 三生石上(FineUI控件)
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
The Register - Security
The Register - Security
The GitHub Blog
The GitHub Blog
B
Blog RSS Feed
F
Fortinet All Blogs
B
Blog
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
罗磊的独立博客
博客园_首页
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
量子位
I
InfoQ
小众软件
小众软件
P
Proofpoint News Feed

Chenxu's Blog

RAG检索优化:从 68% 到 82.2% 学习深度学习 北邮计算机研究生选课指北 学习机器学习 上海篇 提出一个好问题 写代码的环境 选购一台合适的设备 计算机的第零课 序言 内蒙古篇 山东篇 一篇对transformers的疑惑 浅析GPUStack 浅谈后端项目分层 浙江篇 河南篇 一些三端协同的开发工具记录 浅谈编程语言中的 GC 在 Windows 上安装 Rust 美化博客 MyBatis 现代交换原理2024年题目 回忆版 北邮计科本科课程指北 ClkLog埋点用户分析系统研究报告 大数据梧桐实验分享 大数据HBase实验分享 国产向量数据库研究实践 —— 基于 Milvus 的电影推荐系统 服务器环境配置 大数据HDFS实验分享 SSE多服务之间推送数据 数据库系统原理 操作系统 编译原理 手把手教你gozero从开发到部署 (番外篇): 介绍 gtodolist 前端项目 天津篇 北京篇 手把手教你gozero从开发到部署 (5): gtodolist 之任务的删除 前端相关问题 vue3 + element-plus学习 git相关命令 人工智能原理 使用 MongoTemplate 时开启事务 MySQL Redis 力扣刷题笔记之动态规划 记录一次 VSCode 出现的各种奇怪的问题 手把手教你gozero从开发到部署 (4): 在 model 中自己编写函数实现数据库分页查询 记录平时用到的 windows 右键管理 记录平时使用的 linux 的指令 安装 gstore 并使用 java api 手把手教你gozero从开发到部署 (3): gtodolist 之任务的创建和修改 手把手教你gozero从开发到部署 (番外篇): 记录第一次部署 CI/CD 的流程 记录完成 gtodolist 中遇到的 bug 手把手教你gozero从开发到部署 (2): gtodolist 之 user 模块开发 手把手教你gozero从开发到部署 (1): gtodolist 项目说明和环境准备 快速入门 gozero 框架 vue部署在nginx上的相关问题 记一次安装scrapy的报错 将博客部署至服务器 Java CS143: Compliers 《MySQL必知必会》读书笔记(2) 初识 GORM 初识 gin 框架 Spring 《MySQL必知必会》读书笔记(1) 本地搭建博客 🤝友链 🙋🏻‍♂️关于 Browser and Device Check
消息队列
Chenxu · 2024-07-02 · via Chenxu's Blog

RabbitMQ

保证消息不丢失

生产者确认机制: 消息发送到 MQ 后会返回一个结果给发送者, 表示消息是否处理成功.

消息失败后处理方法:

  • 回调方法即时重发
  • 记录日志
  • 保存到数据库然后定时重发, 成功发送后即时删除表中的数据

消息持久化, 默认内存存储消息, 开启持久化确保缓存在 mq 中的消息不丢失:

  • 交换机持久化
  • 队列持久化
  • 消息持久化, SpringAMQP 中的消息默认时持久的, 可以通过MessageProperties中的DeliveryMode指定

消费者确认: 消费者处理消息后向 mq 发送 ack, mq 接受到 ack 后才会删除该消息, SpringAMQP 有三种确认模式:

  • manual: 手动 ack, 业务代码结束后调用 api 发送 ack
  • auto: 自动 ack, 由 spring 检测 listen 代码是否出现异常, 没有异常返回 ack, 否则返回 nack
  • none: 关闭 ack, mq 假定消费者获取消息后会成功处理, 消息投递后立即被删除

利用重试机制, 消费者出现异常时重试. 达到重试次数后, 如果依然失败则将消息投递到异常交换机, 人工介入处理.

消息重复消费

  • 每条消息设置一个唯一标识 id
  • 加锁: 分布式锁, 数据库锁

延迟队列

延迟队列 = TTL + 死信交换机

消息成为死信的条件:

  • 消费者使用basic.reject或者basic.nack声明消费失败, 并且消息的requeue设为false
  • 消息时一个过期消息, 超时无人消费
  • 要投递的队列消息堆积满了, 最早的消息可能成为死信

队列配置了dead-letter-exchange属性, 制定了一个交换机, 则队列中的死信就会投递到这个交换机种, 这个交换机被称为死信交换机 (DLX)

ttl: 一个队列中的消息 ttl 结束仍未消费, 则会变为死信, ttl 超时的两种情况:

  • 消息所在队列设置了存活时间
  • 消息本身设置了存活时间

或者安装延迟队列插件使用延迟队列

消息堆积解决

三种方案:

  • 增加更多消费者, 提高消费速度
  • 在消费者内开启线程池加快消息处理速度
  • 扩大队列容积, 提高堆积上限, 使用惰性队列

惰性队列:

  • 接收到消息后直接存入到磁盘中而非内存
  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储

高可用机制

普通集群

标准集群, 会在集群的各个节点之间共享部分数据, 包括: 交换机, 队列元信息. 不包含队列中的消息.

  • 当访问集群中某节点时, 如果队列不在该节点, 会从数据所在节点传递到当前节点并返回.
  • 队列所在节点宕机, 队列中的消息就会丢失.

一个节点宕机就不可用, 没有高可用

镜像集群

主从模式:

  • 交换机, 队列, 队列中的消息会在各个 mq 镜像节点之间同步备份
  • 创捷队列的节点被称为该队列的主节点, 备份到的其他节点叫做该队列的镜像节点
  • 一个队列的主节点可能是另一个队列的镜像节点
  • 所有操作都是在主节点完成, 然后同步给镜像节点
  • 主节点宕机后, 镜像节点会代替成为新的主节点

同步期间宕机会丢失数据

仲裁队列

用来代替镜像队列:

  • 与镜像队列一样, 主从模式, 支持主从数据同步
  • 主从同步基于 Raft 协议, 强一致性

Kafka

保证消息不丢失

生产者发送消息到 broker 丢失:

  • 设置异步发送, 接受异常记录日志并处理
  • 消息重试

消息在 broker 中存储丢失:

  • 发送确认机制 acks

消费者从 broker 接收消息丢失:

kafka 分区机制: 将每个主题划分为多个分区 (partition)

topic 分区中的消息只能由消费者组中的唯一一个消费者处理, 不同分区分配给同一消费者组的不同消费者

关闭自动提交, 使用手动提交避免消息没有消费/重复消费:

同步+异步提交:

保证消费顺序性

一个 topic 有多个分区, 多个分区无法保证顺序性, 但是分区内偏移量顺序递增, 所以可以:

  • 发送消息时指定分区号
  • 发送消息时按照相同的业务设置相同的 key, kafka 会对 key 哈希来指定分区号

高可用机制

集群: 多个 broker 组成一个 kafka 集群

复制机制:

  • 一个 topic 有多个分区, 每个分区有多个副本, 一个 leader, 其余都是 follower, 副本存储在不同的 broker 中
  • 所有分区副本内容相同, leader 故障时会将一个 follower 提升为 leader
  • follower 有 ISR(in-sync replica, 同步复制) 和普通副本 (异步复制), 优先从 ISR 中选取副本作为 leader

数据清理机制

存储结构:

  • topic 数据存储在分区上, 分区文件过大就会分段存储
  • 每个分段都在磁盘上以索引(xxx.index)和日志文件(xxx.log)形式存储

分段好处:

  • 减少单个文件内容大小,查找数据方便
  • 便于 Kafka 进行日志清理

日志清理策略:

  • 根据消息的保留时间,消息保存时间超过指定时间(默认 168 小时)就会触发清理
  • 根据 topic 存储的数据大小,当日志文件大于阈值则会开始删除最久的消息(默认关闭)

高性能设计

  • 消息分区:存储不受单台服务器限制,处理更多数据
  • 顺序读写:磁盘顺序读写,提高读写效率
  • 页缓存:把磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问
  • 零拷贝:减少上下文切换以及数据拷贝
  • 消息压缩:减少磁盘 IO 和网络 IO
  • 分批发送:将消息打包批量发送,减少网络开销

减少了 页缓存 -> Kafka -> socket 缓存 -> 网卡 的过程