当前位置: 首页 > 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.关键词与标识符...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...