接收完成的数据
broker的响应,是通过监听OP_READ
事件开始的。当有read事件的时候,就会通过SelectionKey找到对应的KafkaChannel。
KafkaChannel接收到响应,就开始读取收到的数据,由于网络传输会有拆包的过程,所以接收数据的时候,就需要进粘包,kafka是这样处理的,首先定义一个消息的大小,用4个字节表示,然后后面跟着消息内容。
比如5aaaaa3bbb4cccc这种消息。
读取的时候会先拿到5,再读取aaaaa,这样第一个消息就读取到了。
然后往下读,拿到3,再读取bbb,这样第二个消息就读取到了。
然后往下读,拿到4,再读取cccc,这样第三个消息就读取到了。
读完后,把数据存在NetworkReceive,并放入KafkaChannel映射的队列中。
当处理完SelectionKey所有的事件后,就开始遍历每个KafkaChannel映射的队列,取出队列头的NetworkReceive存放在completedReceives。
不需要回调的请求
我们在发送请求的时候,会把请求进行了缓存。
有些请求是不需要返回值的,此时就直接封装一个空的ClientResponse,放入到responses列表。
并且从inFlightRequests中,移除对应的ClientRequest。
需要回调的请求
completedReceives是已经拿到的请求,当我们遍历completedReceives的时候,就会根据node的id把inFlightRequests缓存中对应的ClientRequest取出来,如果这个请求需要返回值,就会封装一个ClientResponse,放入ClientResponse列表表。
同样的,对应的ClientRequest也会从inFlightRequests中移除。
失去连接的请求
如果失去了连接,首先就会更改状态为DISCONNECTED。
然后把inFlightRequests对应的ClientRequest都新增一个disconnected为true的ClientResponse。
丢失连接后,就会要求重新拉取元数据。
连接的请求
这个操作就跟上面相反,把已经是CONNECTED的状态,修改为CONNECTED。
处理超时的请求
我们的请求都缓存在inFlightRequests中,所以直接从inFlightRequests缓存中,拿出每个node对应的ClientRequest请求,根据发送请求时间和当前的时间对比,就知道这个ClientRequest是否超时,如果超时了,就关闭对应的Channel。其他操作跟上面的失去连接的请求一样处理。
回调处理
此时,我们已经拿到了ClientResponse的列表,包括不处理的ClientResponse、超时或者端口连接disconnected为true的ClientResponse以及需要处理的ClientResponse。
此时就直接遍历ClientResponse,来处理这些回调。
如果响应里,有异常,但是可以允许重试,就会把RecordBatch重新放入batchs里。
如果有异常,但是不能重试,就把这个异常返回给我们自定义的回调函数。
如果没有异常,就封装好RecordMetadata返回给我们自定义的回调函数。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。