![](https://img-blog.csdnimg.cn/20190918140213434.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
消息中间件
文章平均质量分 61
Kafka、RockectMQ源码
墨玉浮白
这个作者很懒,什么都没留下…
展开
-
RocketMQ NameServer网络通信架构(基于Netty)
初始化Netty是负责监听、处理Broker和客户端发送的网络请求的,NameServer通过9876这个端口接收来自Broker、客户端的网络请求,如Broker注册自己、客户端拉取Broker路由数据等。在构建好NamesrvController后,会通过start方法来启动这一核心组件。首先要初始化NamesrvController//初始化NamesrvControllerboolean initResult = controller.initialize();在这个方法内,会构建Net原创 2021-07-05 15:17:02 · 226 阅读 · 0 评论 -
RocketMQ NameServer启动要初始化哪些参数
distribution/bin/mqnamesrv中启动NameServer进程的命令:sh ${ROCKETMQ_HOME}/bin/runserver.sh org.apache.rocketmq.namesrv.NamesrvStartup $@这行命令执行了runserver.sh,以此启动了NamesrvStartup这个Java类JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MXX:MaxMetaspaceSize=320原创 2021-07-05 14:03:45 · 734 阅读 · 2 评论 -
Kafka Sender线程如何发送数据
文章目录1.内存缓冲中的Batch,如何被判定可发送出去2.标识那些元数据未拉取成功的3.检查筛选出来的Broker是否可以发送数据3.1 元数据是否已经就位3.2 是否可以发送请求3.3 跟Broker建立连接3.3.1 初始化SocketChannel3.3.2 发起连接请求3.3.3 将SocketChannel缓存起来3.4 筛选Broker4.将Broker分组5.淘汰超时的Batch6.为Batch以Broker为单位,构建Request7.将构建好的Request请求发送出去番外篇:完成最终的原创 2021-05-13 11:51:51 · 382 阅读 · 0 评论 -
谈谈对Kafka Accumulator的理解
文章目录前期准备1.获取分区队列Deque2.尝试将消息放到batch中3.基于Buffer Pool,给batch分配一块内存3.1 如何基于缓冲池中的ByteBuffer,复用内存空间3.2 不断申请内存导致可用内存被耗尽咋办?4. 基于double-check模式,再次尝试tryAppend4.1 一条消息是如何按照二进制协议写入到Batch中的ByteBuffer中的4.2 频繁写入消息,如何进入已有的分区的batch中?4.3 如果1个Batch被写满了,如何申请内存构建下一个Batch?5.总结原创 2021-05-07 16:03:44 · 509 阅读 · 0 评论 -
一条消息是如何按照二进制协议写入到Batch中的ByteBuffer中的
double-check模式中会将消息放到Batch中://将消息放到batch中去FutureRecordMetadata future = Utils.notNull(batch.tryAppend(timestamp, key, value, callback, time.milliseconds()));实际调用的是MemoryRecords的的append方法,将消息写入到MemoryRecords的ByteBuffer中://调用MemoryRecord#append方法,将消息放入原创 2021-05-07 13:17:38 · 139 阅读 · 0 评论 -
基于double-check模式尝试将消息放到batch中
多线程并发获取Deque,但只会有一个人会new。然后就会对获取到的Deque加锁,并尝试将消息放入到获取到的Deque的已有的batch中: //对分区队列加锁后,尝试将消息放到队列中的已有的batch中 synchronized (dq) { if (closed) throw new IllegalStateException("Cannot send after the produ原创 2021-05-07 11:09:12 · 136 阅读 · 2 评论 -
Kafka如何基于CopyOnWrite实现线程安全的Deque构建
执行getOrCreateDeque方法,拿着topic的partition,就去拿分区队列Deque(有就拿,没有就创建)。private Deque<RecordBatch> getOrCreateDeque(TopicPartition tp) { //分区作为key,从CopyOnWriteMap中拿分区队列Deque //如果有Deque就拿,没有就创建 Deque<RecordBatch> d = this.batches原创 2021-05-07 10:56:49 · 264 阅读 · 0 评论 -
Kafka将消息发往内存缓冲区
KafkaProducer是多线程并发安全的,多线程环境下也不会导致数据错乱。//将消息添加到内存缓冲里去,RecordAccumulator组件负责的RecordAccumulator.RecordAppendResult result = accumulator.append(tp, timestamp, serializedKey, serializedValue, interceptCallback, remainingWaitMs);首先要从内存缓冲区中找出这个partition对应的De原创 2021-05-03 16:17:31 · 941 阅读 · 0 评论 -
Kafka如何对Topic元数据进行细粒度的懒加载、同步等待?
首先确保Topic的元数据可用,否则消息根本没法往外发。如果以前从没加载过Topic元数据,就会在doSend发送消息时调用waitOnMetadata方法在此同步阻塞住,等待连接Broker成功后拉取元数据。max.block.ms决定了调用send()方法时,最多会被阻塞多长时间。send在一些异常情况下:拉取Topic元数据,连接不到Broker数据放到内存缓冲区,但内存缓冲区已经满了经历这段时间后,就必须得返回了。首先会判断目标Topic的元数据是否已经被加载过了。如果没有,就会把该T原创 2021-04-29 18:05:46 · 413 阅读 · 0 评论 -
客户端发送消息时,源码运行的大致流程
send消息: @Override public Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback callback) { // 如果拦截器为null,就直接拿封装的ProducerRecord //否则就动用拦截器,对发送的消息进行拦截 ProducerRecord<K, V> interceptedRecord = this原创 2021-04-29 14:56:30 · 66 阅读 · 0 评论 -
KafkaProducer初始化时,是否会拉取集群元数据?
debug看一下://核心行为:初始化时,直接调用Metadata组件的方法,从Broker上拉取1次集群元数据,每隔5min刷新一次//在发送消息过程中,如果没找到某个Broker的元数据,也得去拉取一次this.metadata.update(Cluster.bootstrap(addresses), time.milliseconds());会将addresses传进去,并返回包装好的Cluster: //addresses就是我们配置的Broker:[localhost/127.0原创 2021-04-29 11:33:17 · 284 阅读 · 0 评论 -
Kafka Cluster元数据在客户端缓存采用的数据结构
看Cluster类的数据结构1个Node就代表1个Broker,也就代表了1台机器:private final List<Node> nodes;Set维护了Kafka没有被授权访问的Topic列表://没有被授权访问的Topic列表private final Set<String> unauthorizedTopics;由此可见Kafka支持权限控制,如果客户端没有授权访问某个Topic,它就会被放在此处对于Cluster,还通过一些数据结构,维护了客户端缓存的t原创 2021-04-29 11:30:25 · 148 阅读 · 0 评论