当前位置: 首页 > news >正文

kafka之protobuf

Protobuf.proto 文件是一种描述消息结构的定义文件,使用这种文件可以定义数据结构(消息),然后生成对应语言的类或代码用于序列化和反序列化数据。生成 .proto 文件涉及到编写 .proto 文件定义,然后通过 protoc 编译器生成目标语言的代码(如 Java、Python、Go 等)。

生成 .proto 文件的步骤

1. 编写 .proto 文件

首先,手动编写 .proto 文件来定义消息的结构。每个 .proto 文件定义了消息类型、字段以及字段的类型和编号。

例如,下面的 .proto 文件定义了一个图片消息的结构,包括文件名、格式和二进制数据:

// image.proto
syntax = "proto3";message ImageRecord {// 文件名string filename = 1;// 文件格式string format = 2;// 二进制数据bytes imageData = 3;
}
2. 使用 protoc 编译 .proto 文件

protoc 是 Google 的 Protocol Buffers 编译器,负责将 .proto 文件编译成对应编程语言的类文件。这些类文件用于序列化和反序列化数据。

2.1. 安装 protoc
  • 下载并安装 protoc
    • Linux/macOS:使用包管理器安装

# macOS
brew install protobuf# Ubuntu
sudo apt-get install -y protobuf-compiler

Windows:从 官方下载页面 获取并安装。

win 解压上述zip包:

执行的文件就在这里:

为了方便使用可以把这个bin目录配置在系统环境变量里,也可以直接进入到这个文件夹里

如果配置环境变量的话,安装完毕之后验证:

验证安装:

protoc --version
2.2. 编译 .proto 文件

通过 protoc 命令来编译 .proto 文件为目标语言代码。下面是几种常见语言的生成方式。

2.2.1. 生成 Java 代码
# 将 image.proto 编译为 Java 类,生成到指定目录
protoc --java_out=./output image.proto

上述的指令直接在win的cmd命令行里即可完成,记得提前建好 output目录

执行完毕之后就会生成一个 .java文件

编译后,会在 ./output 目录下生成相应的 Java 类(如 ImageRecord.java),你可以直接使用这些类进行 Protobuf 的序列化和反序列化。

3. 使用生成的类

编译生成的类会包含以下功能:

  • 序列化:将定义的消息对象转换为二进制格式,适合传输或存储。
  • 反序列化:将二进制格式的数据解析回消息对象。

例如,使用生成的 Java 类序列化和反序列化 ImageRecord

import com.example.proto.ImageRecord;  // 假设包名为 com.example.proto
import java.nio.file.Files;
import java.io.File;public class ProtobufExample {public static void main(String[] args) throws Exception {// 构建 ImageRecord 消息对象ImageRecord image = ImageRecord.newBuilder().setFilename("example.jpg").setFormat("jpg").setImageData(ByteString.copyFrom(Files.readAllBytes(new File("example.jpg").toPath()))).build();// 序列化为二进制数据byte[] serializedData = image.toByteArray();// 反序列化为 ImageRecord 对象ImageRecord deserializedImage = ImageRecord.parseFrom(serializedData);System.out.println("Filename: " + deserializedImage.getFilename());}
}

4. 定义 .proto 文件的规则

以下是 .proto 文件的常见语法:

  • syntax:定义 Protobuf 版本,推荐使用 proto3,较为简洁并且是最新的标准。

syntax = "proto3";

  • 消息(Message)定义:使用 message 关键字定义数据结构。
message ImageRecord {string filename = 1;  // string 类型字段,字段编号为 1string format = 2;    // string 类型字段,字段编号为 2bytes imageData = 3;  // 二进制数据,字段编号为 3
}

字段类型:常见的 Protobuf 字段类型包括:

  • int32, int64: 整数
  • float, double: 浮点数
  • bool: 布尔值
  • string: 字符串
  • bytes: 二进制数据(如文件、图片、视频)

字段编号:每个字段必须有唯一的编号,编号用于序列化和反序列化。编号必须是正整数,1 到 15 的编号用于最常用的字段,因为它们序列化时占用更少的空间

嵌套消息:可以在消息中定义嵌套的消息类型

message User {string username = 1;Profile profile = 2; // 嵌套消息类型message Profile {string email = 1;int32 age = 2;}
}

总结

  1. 编写 .proto 文件:定义消息结构,包括字段类型、名称和编号。
  2. 使用 protoc 编译:将 .proto 文件编译为目标语言代码,如 Java、Python、Go 等。
  3. 使用生成的类:使用生成的类进行消息的序列化(转换为二进制格式)和反序列化(解析二进制数据)。

kafka和protobuf集成例子:

要将 Protobuf 与 Kafka 集成,我们可以使用 Protobuf 定义的数据结构作为 Kafka 消息体,并通过 Kafka Producer 将序列化的 Protobuf 消息发送到 Kafka。在消费者端,通过 Kafka Consumer 接收消息并反序列化为原始的 Protobuf 对象。

步骤:
  1. 编写 .proto 文件:定义消息的结构。
  2. 使用 protoc 编译生成类:使用 Protobuf 编译器将 .proto 文件编译为 Java/Python 等语言的类。
  3. Kafka Producer 发送 Protobuf 消息:使用生成的类,构造 Protobuf 消息并通过 Kafka Producer 发送。
  4. Kafka Consumer 接收并反序列化 Protobuf 消息:在 Kafka Consumer 中接收消息,并反序列化为 Protobuf 对象。
1. 编写 Protobuf .proto 文件

例如,定义一个包含图片信息的 ImageRecord.proto 文件:

syntax = "proto3";message ImageRecord {string filename = 1;string format = 2;bytes imageData = 3;
}
2. 使用 protoc 编译生成 Java 类

假设使用 Java,将 .proto 文件编译为 Java 类:

protoc --java_out=./output ImageRecord.proto
3. Kafka Producer 发送 Protobuf 消息

通过 Kafka Producer 发送 Protobuf 格式的消息:

import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord}
import java.util.Properties
import java.nio.file.Files
import java.io.File
import com.example.proto.ImageRecordobject ProtobufKafkaProducer {def main(args: Array[String]): Unit = {// Kafka Producer 配置val props = new Properties()props.put("bootstrap.servers", "localhost:9092")props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")props.put("value.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer")val producer = new KafkaProducer[String, Array[Byte]](props)// 构建 Protobuf 消息val imageBytes = Files.readAllBytes(new File("/path/to/image.jpg").toPath)val imageRecord = ImageRecord.newBuilder().setFilename("image.jpg").setFormat("jpg").setImageData(com.google.protobuf.ByteString.copyFrom(imageBytes)).build()// 序列化并发送 Protobuf 消息到 Kafkaval record = new ProducerRecord[String, Array[Byte]]("image_topic", "image_key", imageRecord.toByteArray)producer.send(record)producer.close()}
}
4. Kafka Consumer 接收并反序列化 Protobuf 消息

通过 Kafka Consumer 接收 Protobuf 消息并反序列化:

import org.apache.kafka.clients.consumer.{KafkaConsumer, ConsumerRecords}
import java.util.Properties
import com.example.proto.ImageRecordobject ProtobufKafkaConsumer {def main(args: Array[String]): Unit = {// Kafka Consumer 配置val props = new Properties()props.put("bootstrap.servers", "localhost:9092")props.put("group.id", "test")props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")props.put("value.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer")props.put("auto.offset.reset", "earliest")val consumer = new KafkaConsumer[String, Array[Byte]](props)consumer.subscribe(java.util.Arrays.asList("image_topic"))// 消费并反序列化消息while (true) {val records: ConsumerRecords[String, Array[Byte]] = consumer.poll(100)records.forEach { record =>// 反序列化 Protobuf 消息val imageRecord = ImageRecord.parseFrom(record.value())println(s"Filename: ${imageRecord.getFilename}, Format: ${imageRecord.getFormat}")}}}
}
Kafka 与 Protobuf 集成的优势:
  1. 高效序列化:Protobuf 生成的二进制格式非常紧凑,适合大数据量和高吞吐场景。
  2. 跨语言支持:Protobuf 支持多种语言,因此 Kafka 与 Protobuf 的集成能轻松跨多语言系统工作。
  3. Schema 支持:通过 Protobuf,数据结构的变化可以通过 .proto 文件的模式演进进行管理。

相关文章:

kafka之protobuf

Protobuf 的 .proto 文件是一种描述消息结构的定义文件,使用这种文件可以定义数据结构(消息),然后生成对应语言的类或代码用于序列化和反序列化数据。生成 .proto 文件涉及到编写 .proto 文件定义,然后通过 protoc 编译…...

BARTBERT

BART和BERT都是基于Transformer架构的预训练语言模型。 模型架构: BERT (Bidirectional Encoder Representations from Transformers) 主要是一个编码器(Encoder)模型,它使用了Transformer的编码器部分来处理输入的文本&#xff0…...

C++ 11新特性(1)

文章目录 C11新特性之auto和decltype知识点autoauto推导规则什么时候使用auto? decltypedecltype推导规则 auto和decltype的配合使用 C11新特性之左值引用、右值引用、移动语义、完美转发左值、右值纯右值、将亡值纯右值将亡值左值引用、右值引用 移动语义深拷贝、浅…...

彻底理解浅拷贝和深拷贝

目录 浅拷贝实现 深拷贝实现自己手写 浅拷贝 浅拷贝是指创建一个新对象,这个对象具有原对象属性的精确副本 基本数据类型(如字符串、数字等),在浅拷贝过程中它们是通过值传递的,而不是引用传递,修改值并不…...

Spring4-IoC2-基于注解管理bean

目录 开启组件扫描 使用注解定义bean Autowired注入 场景一:属性注入 场景二:set注入 场景三:构造方法注入 场景四:形参注入 场景五:只有一个构造函数,无注解 场景六:Autowired和Quali…...

AI基础 L22 Uncertainty over Time I 时间的不确定性

Time and Uncertainty 1 Time and Uncertainty States and Observations • discrete-time models: we view the world as a series of snapshots or time slices • the time interval ∆ between slices, we assume to be the same for every interval • Xt: denotes the se…...

中小型企业网络构建

1 什么是 VLAN? VLAN,指的是虚拟局域网,是一种 2 层技术。可以在交换机上实现广播域的隔离。从而可以减小 数据广播风暴对交换网络的影响,降低了网络管理难度,同时可以实现网络规模的灵活扩展。 2 Trunk 链路与 Acces…...

PXE服务

一.PXE服务的功能介绍 1.无盘启动:PXE允许计算机在没有本地存储设备的情况下启动操作系统。这对于构建无盘工作站非常有用,因为计算机可以直接从网络加载操作系统和其他应用程序1。 2.远程安装操作系统:PXE技术可以用于远程安装操作系统&…...

Docker技术深度解析与实践应用

Docker技术深度解析与实践应用 引言 在现代软件开发与部署的浪潮中,Docker作为一种轻量级的容器化技术,凭借其高效、一致和灵活的特性,逐渐成为云原生应用开发和部署的基石。本文将深入探讨Docker的核心概念、技术原理、实践应用&#xff0…...

链动321模式小程序开发源码

链动31模式概述 链动31模式是一种基于技术的新型商业模式,它通过激励用户分享和推广,实现用户、企业和平台的共赢。该模式通常涉及商品展示、积分系统、分享推广和排行榜等功能,旨在通过用户之间的社交裂变来扩大销售和品牌影响力。如何开发这…...

java开发中间件学习记录(持续更新中~)

1 Redis 2JVM 3 java基础底层 4Mysql 5 spring 6 微服务 7.......(持续更新) One:Redis篇 1:Redis 1.穿透 1.1缓存穿透 1.1.1布隆过滤器 1.2缓存击穿 2:击穿 1.3:缓存雪崩 1.4:双写一致 1.5.持久化(RDB,AOF) 1.6…...

(批处理)无限弹窗cmd

代码部分 echo off echo 好了,可以退出了 pause>nul echo 再点就要无限弹窗了! pause >nul echo 你还点? pause >nul echo 再给你最后一次机会,别点了,再点准备重启 pause >nul echo 点击任意键变身奥特曼…...

解决ubuntu 24.04 ibus出现卡死、高延迟问题

问题描述 ubuntu中使用ibus经常会出现卡死、高延迟的问题,网上找了一些解决方法就手动输入命令是重启。但是键盘卡死了没法输入,不能很有效的解决问题。 解决思路 通过一个bash脚本监测ibus进程,当出现进程卡死的时候自动重启。 bash代码…...

减少脏页标记技术中处理时间的方法

减少脏页标记技术中处理时间的方法 一、引言 在数据库系统中,脏页标记技术对于确保数据的一致性和持久性至关重要。然而,脏页标记过程可能会消耗一定的处理时间,影响数据库的性能。因此,寻找有效的方法来减少脏页标记技术中的处理时间具有重要意义。 二、优化数据结构 …...

828华为云征文 | 华为云Flexusx与Docker技术融合,打造个性化WizNote服务

前言 华为云Flexus X实例携手Docker技术,创新融合打造高效个性化WizNote服务。华为云Flexus X实例的柔性算力与Docker的容器化优势相结合,实现资源灵活配置与性能优化,助力企业轻松构建稳定、高效的云端笔记平台。828华为云企业上云节特惠来袭…...

JavaScript事件处理和常用对象

文章目录 前言一、事件处理程序 1.JavaScript 常用事件2.事件处理程序的调用二、常用对象 1.Window 对象2.String 对象3.Date 对象总结 前言 JavaScript 语言是事件驱动型的。这意味着,该门语言可以通过事件触发来调用某一函数或者一段代码。该文还简单介绍了Window…...

Qt基础类05-尺寸类QSize

Qt基础类05-尺寸类QSize 摘要基本信息写在前面重要成员函数举例7个QSize QSize::boundedTo(const QSize &otherSize) constQSize QSize::expandedTo(const QSize &otherSize) constbool QSize::isEmpty() constbool QSize::isNull() constbool QSize::isValid() constQ…...

Vue 2中的this指向详解

在JavaScript中,this的指向是许多开发者经常遇到的问题,尤其是在使用Vue这样的框架时。在Vue 2中,理解this的指向对于正确地访问组件的数据和方法至关重要。 1. this在Vue组件中的指向 在Vue组件的选项中,this通常指向当前组件实…...

长业务事务的离线并发问题

事务指代一组操作同时成功或同时失败,事务可分为两类: 系统事务:即关系数据库事务,一次数据库连接中由start transaction或begin开启,commit表示提交,rollback表示回滚;业务事务:完…...

黑马程序员Java笔记整理(day01)

1.windowsR进入运行,输入cmd 2.环境变量 3.编写java第一步 4.使用idea 5.注释 6.字面量 7.变量 8.二进制 9.数据类型 10.关键词与标识符...

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Java 加密常用的各种算法及其选择

在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

【AI学习】三、AI算法中的向量

在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...