图解 Kafka 网络层实现机制之上篇

在上一篇中,主要带大家深度剖析了「 生产者元数据 」的拉取、管理全流程,今天我们就来聊聊 Kafka 是如何对 Java NIO 进行封装的 ,本系列总共分为3篇,主要剖析以下几个问题:

  1. 针对 Java NIO 的 SocketChannel,kafka 是如何封装统一的传输层来实现最基础的网络连接以及读写操作的?
  2. 剖析 KafkaChannel 是如何对传输层、读写 buffer 操作进行封装的?
  3. 剖析工业级 NIO 实战:如何基于位运算来控制事件的监听以及拆包、粘包是如何实现的?
  4. 剖析 Kafka 是如何封装 Selector 多路复用器的?
  5. 剖析 Kafka 封装的 Selector 是如何初始化并与 Broker 进行连接以及网络读写的?
  6. 剖析 Kafka 网络发送消息和接收响应的整个过程是怎样的?

本篇只讨论前3个问题,剩余的放到后2篇中。

认真读完这篇文章,我相信你会对 Kafka 封装 Java NIO 源码有更加深刻的理解。

这篇文章干货很多,希望你可以耐心读完。

01 总体概述

上篇剖析了「 生产者元数据的拉取和管理的全过程 」,此时发送消息的时候就有了元数据,但是还没有进行网络通信,而网络通信是一个相对复杂的过程,对于 Java 系统来说网络通信一般会采用 NIO 库来实现,所以 Kafka 对 Java NIO 封装了统一的框架,来实现多路复用的网络 I/O 操作 。

为了方便大家理解,所有的源码只保留骨干。

02 Kafka 对 Java NIO 的封装

如果大家对 Java NIO 不了解的话,可以看下这个文档,这里就不过多介绍了。

https://pdai.tech/md/java/io/java-io-nio.html

我们来看看 Kafka 对 Java NIO 组件做了哪些封装? 这里先说下结果,后面会深度剖析。

  1. TransportLayer:它是一个接口,封装了底层 NIO 的 SocketChannel。
  2. NetworkReceive:封装了 NIO 的 ByteBuffer 中的读 Buffer, 对网络编程中的粘包、拆包经典实现 。
  3. NetworkSend:封装了 NIO 的 ByteBuffer 中的写 Buffer。
  4. KafkaChannel:对 TransportLayer、NetworkReceive、NetworkSend 进一步封装,屏蔽了底层的实现细节,对上层更友好。
  5. KafkaSelector:封装了 NIO 的 Selector 多路复用器组件。

接下来我们挨个对上面组件进行剖析。

02 TransportLayer 封装过程

TransportLayer 接口是对 NIO 中 「 SocketChannel 」 的封装。它的实现类总共有 2 个:

  1. PlaintextTransportLayer:明文网络传输实现。
  2. SslTransportLayer:SSL 加密网络传输实现。

本篇只剖析 PlaintextTransportLayer 的实现。

github 源码地址如下:

https://github.com/apache/kafka/blob/2.7/clients/src/main/java/org/apache/kafka/common/network/PlaintextTransportLayer.java
public class PlaintextTransportLayer implements TransportLayer {
    // java nio 中 SelectionKey 事件
    private final SelectionKey key;
    // java nio 中的SocketChannel
    private final SocketChannel socketChannel;
    // 安全相关
    private final Principal principal = KafkaPrincipal.ANONYMOUS;
    // 初始化
    public PlaintextTransportLayer(SelectionKey key) throws IOException {
        // 对 NIO 中 SelectionKey 类的对象引用
        this.key = key;
        // 对 NIO 中 SocketChannel 类的对象引用
        this.socketChannel = (SocketChannel) key.channel();
    }
}

从上面代码可以看出,该类就是 对底层 NIO 的 socketChannel 封装引用 。将构造函数的 SelectionKey 类对象赋值给 key,然后从 key 中取出对应的 SocketChannel 赋值给 socketChannel,这样就完成了初始化工作。

接下来,我们看看几个重要方法是如何使用这2个 NIO 组件的。

02.1 finishConnect()

@Override
// 判断网络连接是否完成
public boolean finishConnect() throws IOException {
    // 1. 调用socketChannel的finishConnect方法,返回该连接是否已经连接完成
    boolean connected = socketChannel.finishConnect();
    // 2. 如果网络连接完成以后就删除对OP_CONNECT事件的监听,同时添加对OP_READ事件的监听
    if (connected)
        // 事件操作
        key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT | SelectionKey.OP_READ);
    // 3. 最后返回网络连接
    return connected;
}

该方法主要用来 判断网络连接是否完成 ,如果完成就关注 「 OP_READ 」 事件,并取消 「 OP_CONNECT 」 事件。

  1. 首先调用 socketChannel 通道的 finishConnect() 判断连接是否完成。
  2. 如果网络连接完成以后就删除对 OP_CONNECT 事件的监听,同时添加对 OP_READ 事件的监听,因为连接完成后就可能接收数据了。
  3. 最后返回网络连接 connected。

二进制位运算事件监听

这里通过「 二进制位运算 」巧妙的解决了网络事件的监听操作,实现非常经典。

通过 socketChannel 在 Selector 多路复用器注册事件返回 SelectionKey ,SelectionKey 的类型包括:

  1. OP_READ:可读事件,值为:1<<0 == 1 == 00000001。
  2. OP_WRITE:可写事件,值为:1<<2 == 4 == 00000100。
  3. OP_CONNECT:客户端连接服务端的事件,一般为创建 SocketChannel 客户端 channel,值为:1<<3 == 8 ==00001000。
  4. OP_ACCEPT:服务端接收客户端连接的事件,一般为创建 ServerSocketChannel 服务端 channel,值为:1<<4 == 16 == 00010000。
key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT | SelectionKey.OP_READ);

首先"~"符号代表按位取反,"&"代表按位取与,通过 key.interestOps() 获取当

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
图解kafka之实战指南.pdf》是一本关于Kafka实践的指南书籍。Kafka是一种高吞吐量、低延迟的分布式消息系统,被广泛应用于大数据和实时流处理领域。 本书逐步介绍了Kafka的基本概念和架构,并提供了详细的实践指南。首先,书中介绍了Kafka的基本原理和术语,包括生产者、消费者、代理、分区和副本等,并通过图解的方式使读者更加直观地理解这些概念。 接着,书中详细介绍了Kafka的部署和配置。读者可以了解到如何搭建Kafka集群、如何配置生产者和消费者,并且介绍了一些常见的配置参数和调优技巧。这些内容将帮助读者实现高性能和高可用的Kafka集群。 然后,书中重点介绍了如何使用Kafka进行实时数据处理和流式计算。作者通过实际案例和代码示例,演示了如何将Kafka与其他工具(如Spark、Flink和Storm)结合使用,以实现数据的实时分析和处理。这对于需要处理大规模实时数据的企业和项目非常有实际意义。 最后,书中还介绍了一些Kafka的最佳实践和应用实例。作者结合自己的经验,提供了一些关于Kafka的使用场景、容错和监控的建议。这些实践指南将帮助读者更好地理解和使用Kafka,提高系统的可靠性和性能。 总之,《图解Kafka之实战指南.pdf》是一本系统而实用的Kafka实践指南,对于想要学习和应用Kafka的开发人员和系统架构师来说,是一本不可多得的参考书籍。通过阅读本书,读者将更加深入地理解Kafka的原理和架构,并掌握如何正确配置和使用Kafka进行实时数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值