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 格式 后面分析报文的时候详细解释. ...
随机推荐
- jumpserver模块功能介绍
一.仪表盘二.用户管理1.用户列表2.用户组 三.资产管理 1.资产列表 1.1 管理资产树 资产树节点不能重名, 右击节点可以添加.删除和重命名节点, 以及进行资产相关的操作 1.2 为资产树节点创 ...
- 在控制台编译运行java程序详细指导
控制台编译运行.java文件 首先在cmd中输入java –version确定java环境变量是否已经配好 其次在cmd中输入javac –version 确定javac环境变量是否已经配好 在用cd ...
- AIX中磁带设备的使用
1.AIX中的磁带设备 在UNIX系统中,磁带一般具有如下共同属性. 磁带密度:指磁带使用时采用的低密度方式和高密度方式 回退操作:磁带一次写入操作完成后,是否立刻倒带,回退到磁带头部. 位置 ...
- Qualcomm_Mobile_OpenCL.pdf 翻译-5-性能优化的概述
这章提供了一个OpenCL应用程序优化的总体概述.更多的细节将会在接下来的章节中找到. 注意:OpenCL程序的优化是具有挑战性的.相比初始的程序开发工作,经常需要做更多的工作. 5.1 性能移植性 ...
- navicat修改表的主键自增长报错
这周自己在构思一个项目的表的设计,由于是第一次,所以走了很多弯路,也遇到了几个问题,这里暂时贴上来. 我用PowerDesign设计出一部分关联表的ER图之后,导出了sql文件之后用navicat导入 ...
- xavier_uniform/xavier_normal
import math from torch.autograd import Variable import torch import torch.nn as nn import warnings w ...
- cve-2019-1609,Harbor任意管理员注册漏洞复现
一.Harbor介绍 以Docker为代表的容器技术的出现,改变了传统的交付方式.通过把业务及其依赖的环境打包进Docker镜像,解决了开发环境和生产环境的差异问题,提升了业务交付的效率.如何高效地管 ...
- 用jquery控制表单提交
可以监听表单submit提交事件给form一个id 吧button的type为submit $(form的id).submit(function(){ if(window.confirm('你确定要取 ...
- dubbo网关
https://blog.csdn.net/Paranoia_ZK/article/details/90743432 springcloud 和 dubbo 混用
- ORACLE中的TOP-N查询(TOP-N分析)、分页查询
TOP-N查询(TOP-N分析):就是获取某一数据集合中的前N条记录,实际应用中经常用到. Oracle中不支持SELECT TOP语句(MySQL中也没用此语句),需要借助ROWNUM伪列来实现TO ...