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

经典八股文之RocketMQ

image

核心概念

NameServer
  • nameserver是整个rocketmq的大脑,是rocketmq的注册中心。
  • broker在启动时向所有nameserver注册。
  • 生产者在发送消息之前先从 NameServer 获取 Broker 服务器地址列表(消费者一 样),然后根据负载均衡算法从列表中选择一台服务器进行消息发送。
  • NameServer 与每台 Broker 服务保持长连接,并间隔 30S 检查 Broker 是否存活,如果检测到 Broker 宕机,则从路由注册表中将其移除。这样就可以实 现 RocketMQ 的高可用。
  • 类似kafka中zookeeper的作用
生产者
消费者
消息
  • 字节数组
Broker
  • 同kafka broker
整体运转
  1. NameServer 先启动
  2. Broker 启动时向 NameServer 注册
  3. 生产者在发送某个主题的消息之前先从 NamerServer 获取 Broker 服务器地址列表(有可能是集群),然后根据负载均衡算法从列表中选择一台
    Broker 进行消息发送。
  4. NameServer 与每台 Broker 服务器保持长连接,并间隔 30S 检测 Broker 是否存活,如果检测到 Broker 宕机(使用心跳机制,如果检测超过
    120S),则从路由注册表中将其移除。
  5. 消费者在订阅某个主题的消息之前从 NamerServer 获取 Broker 服务器地址列表(有可能是集群),但是消费者选择从 Broker 中订阅消息,订阅
    规则由 Broker 配置决定。

分组(Group)
  • 生产者:标识发送同一类消息的 Producer,通常发送逻辑一致。发送普通消息的时候,仅标识使用,并无特别用处。
  • 主要作用用于事务消息:

(事务消息中如果某条发送某条消息的 producer-A 宕机,使得事务消息一直处于 PREPARED 状态并超时,则 broker 会回查同一个 group 的其它 producer, 确认这条消息应该 commit 还是 rollback)

  • 消费者:标识一类 Consumer 的集合名称,这类 Consumer 通常消费一类消息,且消费逻辑一致。同一个 Consumer Group 下的各个实例将共同消费 topic 的消息,起到负载均衡的作用。
  • 消费进度以 Consumer Group 为粒度管理,不同 Consumer Group 之间消费进度彼此不受影响,即消息 A 被 Consumer Group1 消费过,也会再给 Consumer Group2 消费。

Topic主题
  • 标识一类消息的逻辑名字,消息的逻辑管理单位。无论消息生产还是消费,都需要指定 Topic。
  • 区分消息的种类;一个发送者可以发送消息给一个或者多个 Topic;一个消息的接收者可以订阅一个或者多个 Topic 消息
  • Kafka topic

标签
  • RocketMQ支持再发送时给topic打tag,同一个topic的消息虽然逻辑管理是一样的,但消费topic1时,如果你消费订阅的时候指定tagA,那么tagB消息不会订阅
消息队列
  • 同kafka partation
  • 简称 Queue 或 Q。消息物理管理单位。
  • 一个 Topic 将有若干个 Q。若一个 Topic 创建在不同的 Broker,则不同的 broker 上都有若干 Q,消息将物理地 存储落在不同 Broker 结点上,具有水平扩展的能力。
  • 无论生产者还是消费者,实际的生产和消费都是针对 Q 级别。例如 Producer 发送消息的时候,会预先选择(默认轮询)好该 Topic 下面的某一条 Q 发送;Consumer 消费的时候也会负载均衡地分配若干个 Q,只拉取对应 Q 的消息。
  • 每一条 message queue 均对应一个文件,这个文件存储了实际消息的索引信息。并且即使文件被删除,也能通过实际纯粹的消息文件(commit log) 恢复回来。
消息堆积如何解决
  • 提高消费能力
  • 消费者扩容:如果当前Topic的Message Queue的数量大于消费者数量,就可以对消费者进行扩容,增加消费者,来提高消费能力,尽快把积压的消息消费玩。
  • 消息迁移Queue扩容:如果当前Topic的Message Queue的数量小于或者等于消费者数量,这种情况,再扩容消费者就没什么用,就得考虑扩容Message Queue。可以新建一个临时的Topic,临时的Topic多设置一些Message Queue,然后先用一些消费者把消费的数据丢到临时的Topic,因为不用业务处理,只是转发一下消息,还是很快的。接下来用扩容的消费者去消费新的Topic里的数据,消费完了之后,恢复原状。
  • 类似kafka的增加分区
顺序消息如何实现
  • 顺序消息分为全局顺序消息和部分顺序消息
  • 全局顺序消息指某个 Topic 下的所有消息都要保证顺序;
  • 部分顺序消息只要保证每一组消息被顺序消费即可,比如订单消息,只要保证同一个订单 ID 个消息能按顺序消费即可。
    • 订单场景为例,保证每个订单都保证创建、付款、完成的顺序,且每个订单不能互相串联
    • 将不同订单的消息路由到不同的分区中。文档只是给出了Producer顺序的处理,Consumer消费时通过一个分区只能有一个线程消费的方式来保证消息顺序
    • image

    • 同kafka,比如说我们建了一个 topic,有三个 partition。生产者在写的时候,其实可以指定一个 key,比如说我们指定了某个订单 id 作为 key,那么这个订单相关的数据,一定会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的。
  • 全局顺序消息
    • 要保证全局顺序消息, 需要先把 Topic 的读写队列数设置为 一,然后Producer Consumer 的并发设置,也要是一。简单来说,为了保证整个 Topic全局消息有序,只能消除所有的并发处理,各部分都设置成单线程处理 ,这时候就完全牺牲RocketMQ的高并发、高吞吐的特性了。

分布式事务

  • 核心思路利用事务回查,即rocketmq会定时遍历commitlog中的半事务消息
  • RocketMQ不能保证消息不重复,要再消费者端做好幂等性
半事务阶段
  • 生产者发一条消息到rocketmq,但该消息只存在commitlog中,对消费者不可见
commit/rollback阶段
  • 该阶段主要是把 prepared 消息保存到 consumeQueue 中,即让消费端可以看到此消息,也就是可以消费此消息。
  • 如果是 rollback 就不保存

Kafka与Rocketmq的区别

Broker差异
  • 主从差异
    • kafka的master、slave是基于partition维度,leader同步给follower
    • 而rocketmq是基于broker维度,master同步给salve
  • 刷盘
    • rocketmq支持同步刷盘,每次消息刷盘之后再返回
    • kafka内部partation支持异步同步数据
  • 数据写入
    • kafka每个partition独占一个目录,每个partition均有数据文件.log,kafka的topic对应多个partition
    • rocketmq是每个topic共享一个数据文件commitlog

Producer差异
  • 发送方式
    • kafka默认使用异步发送的形式,有一个memory buffer暂存消息,同时会将多个消息整合成一个数据包发送,这样能提高吞吐量,但对消息的实效有些影响;rocketmq可选择使用同步或者异步发送。
  • 发送响应
    • kafka的发送ack支持三种设置:消息存进memory buffer就返回;等到leader收到消息返回,等到leader和ISR的follower都收到消息返回,当然kafka都是异步刷盘。rocketmq都需要等broker的响应确认,有同步刷盘,异步刷盘,同步双写,异步双写等策略,相比于kafka多了一个同步刷盘。

Consumer差异
  • 消息过滤
    • rocketmq的queue和kafka的partition对应,但rocketmq的topic还能更加细分,可对消息加tag,同时订阅时也可指定特定的tag来对消息做更进一步的过滤。
  • 有序消息
    • rocketmq支持全局有序和局部有序,kafka也支持有序消息,但是如果某个broker宕机了,就不能在保证有序了
  • 消费确认
    • rocketmq仅支持手动确认,也就是消费完一条消息ack+1,会定期向broker同步消费进度,或者在下一次pull时附带上offset。kafka支持定时确认,拉取到消息自动确认和手动确认,offset存在zookeeper上
  • 事务支持
    • rocketmq利用事务回查实现分布式事务
    • kafka不支持

相关文章:

  • three.js Raycaster(鼠标点击选中模型)
  • Vue开发中使用Element UI过程中遇到的问题及解决方案Missing required prop: “value”
  • Vue-2、初识Vue
  • leetcode 每日一题 2024年01月01日 经营摩天轮的最大利润
  • insert into select简单数据迁移-postgresql
  • springboot中引入AOP切面编程
  • 万界星空科技云MES,助力客户快速构建数字工厂
  • 在k8s集群中部署多nginx-ingress
  • Centos7.9或Deebian12安装K3s和k9s详细流程
  • C# OpenCvSharp DNN Gaze Estimation
  • centos7安装docker(包含yum配置阿里云镜像源)
  • ubuntu下编译obs-studio遇到的问题记录
  • 淘宝以图搜商品API调用详细步骤(apiKeysecret)
  • 农业银行RPA实践 3大典型案例分析
  • 嵌入式Linux之MX6ULL裸机开发学习笔记(IMX启动方式-启动设备的选择)
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Angularjs之国际化
  • happypack两次报错的问题
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • linux安装openssl、swoole等扩展的具体步骤
  • miaov-React 最佳入门
  • node.js
  • Odoo domain写法及运用
  • PermissionScope Swift4 兼容问题
  • Python学习之路13-记分
  • rc-form之最单纯情况
  • vuex 学习笔记 01
  • WePY 在小程序性能调优上做出的探究
  • 如何进阶一名有竞争力的程序员?
  • 使用 QuickBI 搭建酷炫可视化分析
  • - 转 Ext2.0 form使用实例
  • const的用法,特别是用在函数前面与后面的区别
  • Hibernate主键生成策略及选择
  • Spring第一个helloWorld
  • 阿里云ACE认证之理解CDN技术
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​Python 3 新特性:类型注解
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #13 yum、编译安装与sed命令的使用
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • %@ page import=%的用法
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (第二周)效能测试
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET命令行(CLI)常用命令
  • [ 数据结构 - C++] AVL树原理及实现
  • [@Controller]4 详解@ModelAttribute