今天看到研究Jafka的人还挺多的,比较优秀的是@FrankHui的Kafka系列文章,还有@rockybean 的博客。这两个博客都写的很详细,条理清晰,图文并茂,比起我这种蜻蜓点水,笔记式的记录要好得多了。java
不过其实读源码每一个人侧重点都不一样,我仍是继续记录个人。算法
做为一个实用主义者,我以为读源码有几种目的:mongodb
由于项目中也没有用到Jafka,而是公司内部基于mongodb和netty写的一个MQ,其实我却是更倾向于3和2,而后再带着想法回头改进本身的。既然已经写了是粗略解读,却是不怕人指责了。缓存
Producer的入口能够看ProducerTest
类。网络
根据配置,send()可使用sync和async方式。架构
BlockingChannel
是封装了网络链接的类,底层是NIO的SocketChannel
。async
这里很有意思的是BlockingChannel
的send
方法:学习
<!-- lang: java --> public int send(BoundedByteBufferSend bufferSend) throws IOException { if (!isConnected()) { throw new ClosedChannelException(); } return bufferSend.writeCompletely(writeChannel); }
通常在涉及IO的开发中,咱们都是直接拿一个流,而后用统一的序列化方式,最后写入buffer:ui
<!-- lang: java --> writeChannel.write(encoder.encode(object))
而Jafka里的BoundedByteBufferSend
很显然是Java里面动做名词化的实践之一,bufferSend.writeCompletely(writeChannel)
的含义是:由BoundedByteBufferSend
来决定如何组织数据并写入缓存,而不是在负责网络IO的BlockingChannel
类里统一作处理。这样的方式引入了OO的特性,更为优雅和易维护。一样,Request
也使用了这样的方法writeTo
。.net
MessageSet
是打包消息和传输的类。Jafka压缩消息的算法目前只实现了GZip,GZip在JDK里能够经过GZIPInputStream
实现。
我的对于网络协议这一块比较感兴趣,既然看到了Message,就顺带对Jafka的传输协议进行一下分析。Jafka所用的协议应该是彻底兼容Kafka的。
在Jafka里,全部的请求都会首先带上4个字节的长度,而后才是内容(代码参考BoundedByteBufferSend
里的sizeBuffer
和buffer
):
对于Producer,Producer的message格式以下(代码参考MessageSet.createByteBuffer()
):
在不压缩的状况下,消息仍然是按照4byte长度+内容的方式发送。而压缩是将全部消息混合压缩的。