消息队列知识体系总结(Kafka/RocketMQ)
2022-06-14 23:02:03 0 举报
AI智能生成
登录查看完整内容
消息队列知识体系总结(Kafka/RocketMQ)
作者其他创作
大纲/内容
解耦前
子主题
解耦后
服务解耦
异步处理
没有使用MQ前
使用MQ之后
流量控制
应用场景
总结:通过一个MQ发布订阅消息的模型,Pub/Sub模型,A系统与其它系统解耦
log 位置信息
可能丢失 不会重复
at most once
log 消息处理结果
可能重复 不会丢失
at least once
上面两个都存且存到同一个位置上
不丢失 不重复,只发一次
exactly once
消息策略
核心概念
使用 Netty 来实现异步网络通信
使用 NIO 来实现异步网络通信
网络通信:如何实现高性能的异步网络传输
要想使用网络框架的 API 来传输结构化的数据,必须得先实现结构化的数据与字节流之间的双向转换。
1. 序列化后的数据最好是易于人类阅读的;2. 实现的复杂度是否足够低;3. 序列化和反序列化的速度越快越好;4. 序列化后的信息密度越大越好,也就是说,同样的一个结构化数据,序列化之后占用的存储空间越小越好
序列化考虑因素
Google 的 Protobuf、Kryo、Hessian
JSON、XML 这些标准的数据格式
解决方法
序列化反序列化:如何通过网络传输结构化的数据?
传输协议:应用程序之间对话的语言
内存管理:如何避免内存溢出和频繁的垃圾回收?
数据压缩:时间换空间的游戏
技术要点
RabbitMQ对消息堆积的支持不好,在大量消息堆积时出现性能急剧下降的问题
RabbitMQ 使用 Erlang是比较小众的语言
RabbitMQ
RocketMQ
Kafka最早是由LinkedIn开发,后成为Apache的顶级项目
Kafka的最开始设计的目的是处理海量日志
kafka使用Scala和Java语言开发
由于是异步批量的设计,所以在同步首发消息的响应时延比较高在kafka的broker中都有这样先攒一批在发送一批的处理
kafka使用了批量与异步的思想,异步性能在所有的消息队列中是最强的
Kafka
是最老牌的开源消息队列
ActiveMQ
选型分析
消息队列概述
rabbitmq:优点:轻量,迅捷,容易部署和使用,拥有灵活的路由配置缺点:性能和吞吐量较差,不易进行二次开发rocketmq:优点:性能好,稳定可靠,有活跃的中文社区,特点响应快缺点:兼容性较差,但随意影响力的扩大,该问题会有改善kafka:优点:拥有强大的性能及吞吐量,兼容性很好缺点:由于“攒一波再处理”导致延迟比较高pulsar:采用存储和计算分离的设计,是消息队里产品中黑马,值得持续关注
总结
在 Kafka 中,发布订阅的对象
可以为每个业务、每个应用甚至是每类数据都创建专属的主题
每条消息属于且仅属于一个Topic
发送和订阅消息都必须指定topic
主题(Topic)
Kafka 中的分区机制指的是将每个主题划分成多个分区(Partition)
topic的组成单元,可以水平扩容,是kafka高吞吐量的保障
消息持久化时,每条消息都是根据一定的分区规则路由到对应的partition中,并append到log文件的尾部
在同一个partition中消息是顺序写入且有序的,但不同partiton之间不能保证消息的有序性
个数最好与服务器个数相当
多个大小相等的segment file (段)组成了一个partition
partition可以有指定数据的副本,备份的思想很简单,就是把相同的数据拷贝到多台机器上,而这些相同的数据拷贝在 Kafka 中被称为副本(Replica)主从模式,producer和consumer只与leader交互follower从leader复制
副本(Replica)
对外提供服务,这里的对外指的是与客户端程序进行交互
领导者副本(Leader Replica)
只是被动地追随领导者副本而已,不能与外界进行交互
追随者副本(Follower Replica)
副本分类
in-sync replica,已同步的副本
Kafka会在Zookeeper上针对每个Topic维护一个ISR,持有partition的已同步的副本信息,如果某个分区的Leader不可用,Kafka就会从ISR集合中选择一个副本作为新的Leader。
ISR
备份机制(Replication)
生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,它只做一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。
分区(Partitioning)
副本从属于分区
Leader副本
Follower副本
LEO
HW
处于同步失效或功能失效(比如副本处于非存活状态)的副本统称为失效副本
replica.lag.time.max.ms
replica.lag.max.messages
判断标准
follower 副本进程卡住,在一段时间内根本没有向 leader 副本发起同步请求,比如频繁的 Full GC
follower 副本进程同步过慢,在一段时间内都无法追赶上 leader 副本,比如 I/O 开销过大。
副本失效原因
失效副本
副本相关概念
定义
副本
每个partition 就相当于一个巨型的文件 里面由多个大小相等的segment file小文件组成,但是每个segment file 的消息数量并不一定相等,
包含若干索引条目,每个条目表示数据文件中一条message的索引
.index 索引文件
.log 数据文件
组成
setment file
partition中的每个消息都有一个连续的序号,用于partition唯一标识一条消息。Offset记录着下一条将要发送给Consumer的消息的序号。Offset从语义上来看拥有两种:Current Offset和Committed Offset。
位移
Current Offset保存在Consumer中,它表示Consumer希望收到的下一条消息的序号。它仅仅在poll()方法中使用。例如,Consumer第一次调用poll()方法后收到了20条消息,那么Current Offset就被设置为20。这样Consumer下一次调用poll()方法时,Kafka就知道应该从序号为21的消息开始读取。这样就能够保证每次Consumer poll消息时,都能够收到不重复的消息。
current offset
已提交位移,保存在Broker上,表示Consumer已经确认消费过的消息的序号,举个例子,Consumer通过poll() 方法收到20条消息后,此时Current Offset就是20,经过一系列的逻辑处理后,并没有调用consumer.commitAsync()或consumer.commitSync()来提交Committed Offset,那么此时Committed Offset依旧是0。
Committed Offset
offset
Current Offset是针对Consumer的poll过程的,它可以保证每次poll都返回不重复的消息;而Committed Offset能够保证新的Consumer能够从正确的位置开始消费一个partition,从而避免重复消费。
向主题发布消息的客户端应用程序称为生产者
生产者程序通常持续不断地向一个或多个主题发送消息
生产者(Producer)
订阅这些主题消息的客户端应用程序就被称为消费者
消费者也能够同时订阅多个主题的消息
消费者(Consumer)
Kafka 提供的可扩展且具有容错性的消费者机制
可以有一个或多个 Consumer
同一个 GroupId
消息只能被同组内一个 Consumer 消费
Coordinator 协调者
消费者组(Consumer Group)
负责存储消息的服务端进程
Broker 负责接收和处理客户端发送过来的请求
对消息进行持久化
Broker
消息是顺序进入,顺序消费队列中的每一条消息只能被一个消费者消费
队列模型
发布订阅模型
消息队列模型
架构图
生产者消费者统称为客户端(Clients)
groupid-topic-partition -> offset的方式保存。实际上保存在__consumers_offsets这个topic中。
存储模型
Broker的服务进程构成(Servers)
集群高可用
同步双写
异步复制
本地存储,主从复制,多副本拷贝
数据高可用
服务高可用
采用发送确认机制
消息可靠投递(producer)
采用消费确认机制
消息可靠消费(consumer)
同步刷盘,持久化消息
同步多写:多副本策略+同步刷盘持久化消息
broker对写入消息的payload做完整性校验
消息可靠存储(broker)
消息堆积能力
消息处理高可用
高可用机制
延迟毫秒级别
吞吐(单机万到百万TPS)
性能标准
异步发送
Producer 端可以在内存中合并多条消息后, 以一次请求的方式发送了批量的消息给 broker,从而大大减少 broker 存储消息的 IO 操作次数。
但也一定程度上影响了消息的实时性,相当于以时延代价,换取更好的吞吐量。
批量发送
由于消息 topic 由多个 partition 组成, 且 partition 会均衡分布到不同 broker 上,因此,为了有效利用 broker 集群的性能,提高消息的吞吐量,
producer 可以通过随机或者 hash 等方式,将消息平均发送到多个 partition 上,以实现负载均衡。
负载均衡(producer)
Producer 端可以通过 GZIP 或 Snappy 格式对消息集合进行压缩。 Producer 端进行压缩之后,在Consumer 端需进行解压。压缩的好处就是减少传输的数据量,减轻对网络传输的压力,在对大数据处理上,瓶颈往往体现在网络上而不是 CPU(压缩和解压会耗掉部分 CPU 资源)
压缩( GZIP 或 Snappy)
消息高性能投递(producer)
多分区(Partition/Queue)策略,并行读写
Page Cahce
Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。 官网有数据表明,同样的磁盘,顺序写能到 600M/s,而随机写只有 100K/s。这与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。
顺序IO
异步刷盘
持久化
每个分区里面就是很多个LogSegmentFile,也就是日志段文件
0000000-5367851
00000000000000000000.index00000000000000000000.log00000000000000000000.timeindex
5367851-9987654
00000000000005367851.index00000000000005367851.log00000000000005367851.timeindex
9987654就是这个消息写入到此SegmentFile的起始offset
00000000000009987654.index00000000000009987654.log00000000000009987654.timeindex
每个分区的数据会被分成多个段,放在多个文件里,每个文件还有自己的索引文件限定了每个日志段(LogSegmentFile)的大小为1G,存满了就新建另一个日志段
消息日志分段存储
使用稀疏索引
限定了在日志文件中每写入多少条数据,就要在索引中写入一条索引数据,默认是4KB
由索引文件的物理位置定位到某条数据,再向下遍历。偏移量是有序的
消息日志二分查找
消息读取
消息高性能存储(broker)
多consumer示例并行消费topic
零拷贝
批量拉取消息
消息高性能消费(consumer)
高性能机制
发送流程图
在新版本的kafka中(从0.9开始),其实只有异步方式一种,是批量发送的方式在producer端,存在2个线程,一个是producer主线程,用户端调用send消息时,是在主线程执行的,数据被缓存到RecordAccumulator中,send方法即刻返回,也就是说此时并不能确定消息是否真正的发送到broker。另外一个是sender IO线程,其不断轮询RecordAccumulator,满足一定条件后,就进行真正的网络IO发送,使用的是异步非阻塞的NIO。主线程的send方法提供了一个用于回调的参数,当sender线程发送完后,回调函数将被调用,可以用来处理成功,失败或异常的逻辑
producer工作流程
指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值;
既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition值,也就是常说的 round-robin 算法。
producer 分区策略
目的:为保证 producer 发送的数据,能可靠的发送到指定的 topic, topic 的每个 partition 收到producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果producer 收到 ack, 就会进行下一轮的发送,否则重新发送数据。
何时发送ack?确保有follower与leader同步完成,leader再发送ack,这样才能保证leader挂掉之后,能在follower中选举出新的leader。
延迟低,不用等待所有follower都同步完
但是容错率低,同样为了容忍 n 台节点的故障,需要 2n+1 个副本
半数以上的follower同步完成,即可发送ack继续发送重新发送
延迟高,但网络延迟对kafka影响小
容错率高,同样为了容忍n台节点的故障,只需要 n+1 个副本
全部的follower同步完成,才可以发送ack(kafka选择的这种)
0: producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟, broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据;
1:producer 等待 broker 的 ack, partition 的 leader 落盘成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么将会丢失数据
-1(all) : producer 等待 broker 的 ack, partition 的 leader 和 ISR 的follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后, broker 发送 ack 之前, leader 发生故障,那么会造成数据重复。
ACK机制配置说明
ACK 发送策略
出现背景: leader 收到数据,所有 follower 都开始同步数据,但有一个 follower,因为某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去,直到它完成同步,才能发送 ack
解决策略:ISR意味和leader保持同步的follow集合,当 ISR 中的 follower 完成数据的同步之后,就会给 leader 发送 ack。
batch批量发送数据原因,会导致follow频繁进出ISR,然后导致频繁更改存储在Zookeeper中的ISR信息
如果follow与leader信息条数相差大于replica.lag.max.message就踢出ISR
如果leader与follow超过replica.lag.time.max.ms时间为同步,就从ISR中踢出(kafka选的这个)
如何选择ISR中的follow:选择与leader通信频繁的,数据相差小的follow
ISR(in-sync replica set)
Broker防止消息丢失机制
LEO:(Log End Offset)每个副本的最后一个offset
HW:(High Watermark)高水位,指的是消费者能见到的最大的 offset, ISR 队列中所有follow中最小的 LEO
follower 故障:follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后, follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
leader 故障:leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性, 其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。
只保证数据一致性,不保证数据不丢失或者不重复(由ACK保证)
数据一致性问题
将服务器的 ACK 级别设置为-1(all),可以保证 Producer 到 Server 之间不会丢失数据,即 At Least Once 语义。
相对的,将服务器 ACK 级别设置为 0,可以保证生产者每条消息只会被发送一次,即 At Most Once 语义
At Least Once 可以保证数据不丢失,但是不能保证数据不重复;相对的, At Most Once可以保证数据不重复,但是不能保证数据不丢失。 但是,对于一些非常重要的信息,比如说交易数据,下游数据消费者要求数据既不重复也不丢失,即 Exactly Once 语义。
PID:生产者表示
SequenceNumber:消息的序列化号
paratition:分区
0.11 版本的 Kafka,引入了一项重大特性:幂等性。所谓的幂等性就是指 Producer 不论向 Server 发送多少次重复数据, Server 端都只会持久化一条。
如果pid+partition对应的SequenceNumber重复时,则代表这组消息是重复数据,broker只会持久化一条
At Least Once + 幂等性 = Exactly Once,也就是不丢消息,也没有重复消费
ExactlyOnce
解决的问题
每个客户端都会给producer生成一个TransactionId,并且TransactionId与Pid进行绑定,TransactionId被维护在Transaction Coordinator中,每次producer都会去coordinator中找相应TransactionId锁对应的自己的Pid,就能保证一个生产者的Pid不会变化
解决方式
producer事务
producer分析
push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的。它的目标是尽可能以最快速度传递消息,但是这样很容易造成 consumer 来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。
push
pull 模式不足之处是,如果 kafka 没有数据,消费者可能会陷入循环中, 一直返回空数据。 针对这一点, Kafka 的消费者在消费数据时会传入一个时长参数 timeout,如果当前没有数据可供消费, consumer 会等待一段时间之后再返回,这段时长即为 timeout。
pull(kafka选用的)
消息队列消费方式
consumer group中的新增或删除某个consumer,导致其所消费的分区需要分配到组内其他的consumer上
consumer订阅的topic发生变化,比如订阅的topic采用的是正则表达式的形式,如test-*此时如果有一个新建了一个topic test-user,那么这个topic的所有分区也是会自动分配给当前的consumer的,此时就会发生再平衡
consumer所订阅的topic发生了新增分区的行为,那么新增的分区就会分配给当前的consumer,此时就会触发再平衡
再平衡策略的触发事件
尝试将t0-0分配给C0,由于C0订阅了t0,因而可以分配成功;尝试将t1-0分配给C1,由于C1订阅了t1,因而可以分配成功;尝试将t1-1分配给C2,由于C2订阅了t1,因而可以分配成功;尝试将t2-0分配给C0,由于C0没有订阅t2,因而会轮询下一个consumer;尝试将t2-0分配给C1,由于C1没有订阅t2,因而会轮询下一个consumer;尝试将t2-0分配给C2,由于C2订阅了t2,因而可以分配成功;同理由于t2-1和t2-2所在的topic都没有被C0和C1所订阅,因而都不会分配成功,最终都会分配给C2
round-robin是轮询,它是按照消费者组为主要目标的,也就是把消费者组中所有consumer订阅的所有topic-partition都组合起来,根据这些topic-partition的hash值进行排序,然后再从头依次循环发送给消费者组中的每个消费者,如果分配给这个consumer的topic是它没有订阅的,那么就轮询下一个,指导将这个topic-partition分配给最近的一个订阅了它的consumer。可以看出轮询方式会导致消费者组中,每个cosumer所承载的分区数量不一致,从而导致消费者组中consumer的压力不一致
round-robin
假设有两个consumer:C0和C1,两个topic:t0和t1,这两个topic分别都有三个分区,那么总共的分区有六个:t0-0、t0-1、t0-2、t1-0、t1-1和t1-2。那么Range分配策略将会按照如下步骤进行分区的分配:
range是重分配策略,它是按照topic为主题的,也就是把订阅了这个topic的消费者组的所有消费者都组合起来,将topic的分区进行均匀分布(但是当topic的partition数量/消费者组的consumer数量!=整数时,分配还是不均匀的,还会导致消费者组中每个consumer的压力不一致)
range
将现有的分区尽可能均衡的分配给各个consumer,存在此目的的原因在于Round Robin和Range分配策略实际上都会导致某几个consumer承载过多的分区,从而导致消费压力不均衡
如果发生再平衡,那么重新分配之后在前一点的基础上会尽力保证当前未宕机的consumer所消费的分区不会被分配给其他的consumer上
目的
首先将所有的分区进行排序,排序方式为:首先按照当前分区所分配的consumer数量从低到高进行排序,如果consumer数量相同,则按照分区的字典序进行排序。这里六个分区由于所在的topic的订阅情况各不相同,因而其排序结果如下
初始状态分配的特点是,所有的分区都还未分配到任意一个consumer上。这里我们假设有三个consumer:C0、C1和C2,三个topic:t0、t1和t2,这三个topic分别有1、2和3个分区,那么总共的分区为:t0-0、t1-0、t1-1、t2-0、t2-1和t2-2。关于订阅情况,这里C0订阅了t0,C1订阅了t0和1,C2则订阅了t0、t1和t2。
然后将所有的consumer进行排序,其排序方式为:首先按照当前consumer已经分配的分区数量有小到大排序,如果两个consumer分配的分区数量相同,则会按照其名称的字典序进行排序。由于初始时,这三个consumer都没有分配任何分区,因而其排序结果即为其按照字典序进行排序的结果:
然后将各个分区依次遍历分配给各个consumer,首先需要注意的是,这里的遍历并不是C0分配完了再分配给C1,而是每次分配分区的时候都整个的对所有的consumer从头开始遍历分配,如果当前consumer没有订阅当前分区,则会遍历下一个consumer。然后需要注意的是,在整个分配的过程中,各个consumer所分配的分区数是动态变化的,而这种变化是会体现在各个consumer的排序上的,比如初始时C0是排在第一个的,此时如果分配了一个分区给C0,那么C0就会排到最后,因为其拥有的分区数是最多的
接下来的t2-1和t2-2,由于也只有C2订阅了t2,因而其最终还是会分配给C2,最终在t2-0、t2-1和t2-2分配完之后,各个consumer的排序以及其分区分配情况如下:
首先将t2-0尝试分配给C0,由于C0没有订阅t2,因而分配不成功,继续轮询下一个consumer;然后将t2-0尝试分配给C1,由于C1没有订阅t2,因而分配不成功,继续轮询下一个consumer;接着将t2-0尝试分配给C2,由于C2订阅了t2,因而分配成功,此时由于C2分配的分区数发生变化,各个consumer变更后的排序结果为:
尝试将t0-0分配给C0,由于C0订阅了t0,因而分配成功,最终的分配结果为
接着继续分配t1-0,首先尝试将其分配给C0,由于C0没有订阅t1,因而分配不成功,继续轮询下一个consumer;然后尝试将t1-0分配给C1,由于C1订阅了t1,因而分配成功同理,接下来会分配t1-1,虽然C1和C2都订阅了t1,但是由于C1排在C2前面,因而该分区会分配给C1
与前面讲解的Round Robin进行对比,可以很明显的发现,Sticky重分配策略分配得更加均匀一些
实现步骤
Sticky:这种分区策略是最新版本中新增的一种策略,其主要实现了两个目的
sticky
再平衡策略
分区分配策略(再平衡策略)
Kafka 0.9 版本之前, consumer 默认将 offset 保存在 Zookeeper 中,从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为__consumer_offsets
offset的是以ConsumerGroup+Topic+Partition来分类存储的,因为消费者可能从消费者组中加入或者宕机,具有不确定性,所以需要通过消费者组来作为唯一标识
consumer的offset的存储
由于每个Topic-Partition对应的存储offset的segment有多个,而kafka消费者可以批量消费数据,如果这批数据是跨了2个segment的,而刚好消费者消费消息失败,需要再次消费。但此时第一个segment过期了,就无法消费到第一个segment中的消息了。这是事务所无法保证的。
Consumer事务(保证相对较弱)
consumer分析
broker分析
一个系统挂掉就都挂掉
1.系统间解耦
2.峰值压力缓冲
3.异步(并行)通信
1.未提供事务性
2.没有消息确认机制
3.没有消息分组
kafka做消息系统的不足之处
消息重发
消息发送丢失
kafka不能保证消息的绝对可靠
4.常规消息系统
5.活动跟踪
格式化消息(装饰)
将多个消息存放在同一个通知里发送
根据用户配置的首选项发送数据
好处
6.传递消息
和flume整合
7.度量指标和日志记录
和es整合
8.提交日志
和sparkStreaming整合
和kafka整合
9.流处理
kafka常用场景
第一级消息类型,书的标题
队列(Queue)
第二级消息类型,书的目录,可以基于 Tag 做消息过滤
Tag
broker-master
broker-salve
这种方式风险较大,一旦 Broker 重启或者宕机时,会导致整个服务不可用,不建议线上环境使用。
单个 Master
一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master
优点:配置简单,单个 Master 宕机或重启维护对应用无影响,在磁盘配置为 RAID10时,即使机器宕机不可恢复情况下,由与 RAID10 磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢)。性能最高。
缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到受到影响。
多 Master 模式
每个 Master 配置一个 Slave,有多对 Master-Slave, HA 采用异步复制方式,主备有短暂消息延迟,毫秒级。
优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为 Master 宕机后,消费者仍然可以从 Slave 消费,此过程对应用透明。不需要人工干预。性能同多Master 模式几乎一样。
缺点: Master 宕机,磁盘损坏情况,会丢失少量消息。
多 Master 多 Slave 模式异步复制
每个 Master 配置一个 Slave,有多对 Master-Slave, HA 采用同步双写方式,主备都写成功,向应用返回成功。
优点:数据与服务都无单点, Master 宕机情况下,消息无延迟,服务可用性与数据可用性都非常高
缺点:性能比异步复制模式略低,大约低 10%左右,发送单个消息的 RT 会略高。目前主宕机后,备机不能自动切换为主机,后续会支持自动切换功能。
多 Master 多 Slave 模式同步双写
Broker部署方式
Name Server
概要
消息可靠投递
消息可靠消费
消息高性能投递
消息高性能消费
https://www.processon.com/mindmap/5fa74813079129448c940da3
https://www.processon.com/view/5f93cf947621311c479e49e7?fromnew=1
参考资料
消息队列知识体系总结(Kafka/RocketMQ)
0 条评论
回复 删除
下一页