kafka 通信报文格式
1. 序列化一条消息
消息有 key 和 value
kafka 提供了基础数据类型的序列化工具,对于业务的自定义类需要自行实现序列化
ProducerRecord 是对象,含 KV 和 headers,此时的 KV 还是对象
在 KafkaProducer#doSend 中会对 KV 进行序列化,得到 KV 的 byte 数组
然后把 byte 数组和 headers 加入到 ProducerBatch 中
代码见:
org.apache.kafka.clients.producer.internals.ProducerBatch#recordsBuilder
org.apache.kafka.common.record.MemoryRecordsBuilder#appendStream
2. kafka 的 tcp 报文
利用 Struct 和 Schema 把 ProducerBatch 的数据转换成符合 kafka 格式的 tcp 报文
以发送消息为例
org.apache.kafka.common.requests.AbstractRequest#toSend
org.apache.kafka.common.requests.AbstractRequest#serialize
org.apache.kafka.common.requests.AbstractRequestResponse#serialize
org.apache.kafka.common.requests.ProduceRequest#toStruct
org.apache.kafka.common.protocol.types.Schema#write
org.apache.kafka.common.requests.RequestHeader#toStruct
public Struct toStruct() {
Schema schema = schema(apiKey.id, apiVersion);
Struct struct = new Struct(schema);
struct.set(API_KEY_FIELD_NAME, apiKey.id);
struct.set(API_VERSION_FIELD_NAME, apiVersion);
// only v0 of the controlled shutdown request is missing the clientId
if (struct.hasField(CLIENT_ID_FIELD_NAME))
struct.set(CLIENT_ID_FIELD_NAME, clientId);
struct.set(CORRELATION_ID_FIELD_NAME, correlationId);
return struct;
}
org.apache.kafka.common.requests.ProduceRequest#toStruct
public Struct toStruct() {
// Store it in a local variable to protect against concurrent updates
Map<TopicPartition, MemoryRecords> partitionRecords = partitionRecordsOrFail();
short version = version();
Struct struct = new Struct(ApiKeys.PRODUCE.requestSchema(version));
Map<String, Map<Integer, MemoryRecords>> recordsByTopic = CollectionUtils.groupDataByTopic(partitionRecords);
struct.set(ACKS_KEY_NAME, acks);
struct.set(TIMEOUT_KEY_NAME, timeout);
struct.setIfExists(NULLABLE_TRANSACTIONAL_ID, transactionalId);
List<Struct> topicDatas = new ArrayList<>(recordsByTopic.size());
for (Map.Entry<String, Map<Integer, MemoryRecords>> topicEntry : recordsByTopic.entrySet()) {
Struct topicData = struct.instance(TOPIC_DATA_KEY_NAME);
topicData.set(TOPIC_NAME, topicEntry.getKey());
List<Struct> partitionArray = new ArrayList<>();
for (Map.Entry<Integer, MemoryRecords> partitionEntry : topicEntry.getValue().entrySet()) {
MemoryRecords records = partitionEntry.getValue();
Struct part = topicData.instance(PARTITION_DATA_KEY_NAME)
.set(PARTITION_ID, partitionEntry.getKey())
.set(RECORD_SET_KEY_NAME, records);
partitionArray.add(part);
}
topicData.set(PARTITION_DATA_KEY_NAME, partitionArray.toArray());
topicDatas.add(topicData);
}
struct.set(TOPIC_DATA_KEY_NAME, topicDatas.toArray());
return struct;
}
组装报文
public abstract class AbstractRequestResponse {
/**
* Visible for testing.
*/
public static ByteBuffer serialize(Struct headerStruct, Struct bodyStruct) {
ByteBuffer buffer = ByteBuffer.allocate(headerStruct.sizeOf() + bodyStruct.sizeOf());
headerStruct.writeTo(buffer);
bodyStruct.writeTo(buffer);
buffer.rewind();
return buffer;
}
}
public class NetworkSend extends ByteBufferSend {
public NetworkSend(String destination, ByteBuffer buffer) {
super(destination, sizeDelimit(buffer));
}
private static ByteBuffer[] sizeDelimit(ByteBuffer buffer) {
return new ByteBuffer[] {sizeBuffer(buffer.remaining()), buffer};
}
private static ByteBuffer sizeBuffer(int size) {
ByteBuffer sizeBuffer = ByteBuffer.allocate(4);
sizeBuffer.putInt(size);
sizeBuffer.rewind();
return sizeBuffer;
}
}
所以能推断出,kafka 报文格式:4 字节存储长度,headerStruct,bodyStruct
当然通过 NetworkSend 和 NetworkReceive 的注释也能看出来
kafka 通信报文格式的更多相关文章
- HTTP协议报文格式
HTTP协议报文格式 接下来我们看看HTTP协议(Hypertext Transfer Protocol――超文本传输协议)浏览器端(客户端)向WEB服务器端访问页面的过程和HTTP协议报文的格式. ...
- MQTT——控制报文格式
解控制报文格式是学习MQTT中,笔者认为最为重要的一个知识点.MQTT的所有行为都离不开他.控制报文可以分为三个部分组成,分别为:固定报头.可以变报头.有效载荷部分. 注意:上面的说的报文的类型.是指 ...
- 第11章 拾遗4:IPv6(1)_报文格式和地址类型
1. IPv4和IPv6协议栈的比较 (1)IPv6取代IPv4,支持IPv6的动态路由协议都属于IPv6协议(如RIPng.OSPFv3). (2)Internet控制消息协议IPv6版(ICMPv ...
- 总想自己动动手系列·1·本地和外网(Liunx服务器上部署的web项目)按照自定义的报文格式进行交互(准备篇)
一.准备工作 (1)有一台属于自己的云服务器,并成功部署和发布一个web项目(当然,本质上来说Java-Project也没问题),通过外网IP可以正常访问该web项目. 需要说明的是:任何web项目, ...
- 结合Wireshark捕获分组深入理解TCP/IP协议栈之TCP协议(TCP报文格式+三次握手实例)
摘要: 本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠 ...
- TCP报文格式+UDP报文格式+MAC帧格式
TCP和UDP的区别: 1)TCP是面向连接的,而UDP是无连接的 2)TCP提供可靠服务,而UDP不提供可靠服务,只是尽最大努力交付报文 3)TCP面向字节流,TCP把数据看成一串无结构的字节流,而 ...
- 【转】IP报文格式详解
下图为常见的IP报文格式表: 上面是IP的报文格式,接下来我们先说明各个字段的意义.然后,用Etheral软件转包分析IP的报文格式. 1.版本:ip报文中,版本占了4位,用来表示该协议采用的是那一个 ...
- TCP协议探究(一):报文格式与连接建立终止
一 TCP:传输控制协议报文格式 1 TCP服务 提供面向连接.可靠的字节流服务 面向连接意味着两方通信,不支持多播和广播 可靠性的支持: 应用数据被分割成TCP认为最适合发送的数据块.由TCP传递给 ...
- DNS报文格式(RFC1035)
一.域名和资源记录的定义 1.Name space definitions 2.资源记录定义(RR definitions) 2.1 格式 后面分析报文的时候详细解释. ...
随机推荐
- CSS3之box-shadow--阴影外阴影与外发光
基础语法 外阴影:box-shadow:X Y Npx #color; 内阴影:box-shadow:inset X Y Npx #color; 第一个属性:阴影的X轴(可以使用负值) 第二个属性:阴 ...
- 点亮指路灯led
为什么要使用LED? (bootloader,kernel)开发初期,由于串口等硬件尚未被初始化,因此调试手段相当有限,这时通常会采用LED来做为程序调试的重要手段. LED驱动设计: 1.设置GPI ...
- DTM/DEM/DSM/DOM/DLG
一.DTM (Digital Terrain Model) 数字地面模型是利用一个任意坐标系中大量选择的已知x .y .z 的坐标点对连续地面的一个简单的统计表示,或者说,DTM 就是地形表面形态属性 ...
- 右则css 小浮条
<!--右边浮动--> <div class="indexfu"> <div class="indexfu2" id=" ...
- 2019长安大学ACM校赛网络同步赛 J Binary Number(组合数学+贪心)
链接:https://ac.nowcoder.com/acm/contest/897/J 来源:牛客网 Binary Number 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32 ...
- share point 已在此服务器场中安装 ID 为 15/b7a69889-1789-4855-b8bd-9a3b4cfd7fc0 的功能。请使用强制属性显式地重新安装此功能。
部署步骤“添加解决方案”中出现错误: 已在此服务器场中安装 ID 为 15/b7a69889-1789-4855-b8bd-9a3b4cfd7fc0 的功能.请使用强制属性显式地重新安装此功能. 英文 ...
- ESP8266内置的定时器库--Ticker库
Ticker的功能非常简单,就是规定时间后调用函数 总体上,根据功能可以把方法分为两大类: 定时器管理方法: 定时器启用方法: detach() 停止定时器 active() 定时器是否 ...
- Linux基本命令+Makefile
1.linux下查看进程占用cpu的情况(top): 格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 主要参数 d:指定更新的间隔,以秒计算. q:没有任何延 ...
- pandas Series和dataframe
DataFrame是一个表格型数据结构,与Series不同的是,DataFrame可以含有一组或者有序的列,每列可以使不同的值的类型,它可以被看做成Series的字典.
- java总结2
1,对象数组,必须指定了数组长度,长度是固定的 2,除了ArrayList<E>以外,类赋值给变量,只有string类拿到的是值,其他类拿到的都是类的地址值, ArrayList<E ...