Tecnología de serialización ProtoBuf
ProtoBuf: https://developers.google.cn/protocol-buffers
1. ¿Qué es la serialización?
Transforme el contenido del objeto en un flujo de datos;
Correspondiente a esto es la deserialización: lea datos del flujo de datos y luego vuelva a convertirlos en un objeto;
La serialización y la deserialización a menudo siguen un cierto formato para operar;
Las serializaciones comunes incluyen: convertir objetos en flujos XML, JSON y binarios
características | XML | JSON | protobuf |
---|---|---|---|
estructura de datos | complejo | respuesta corta | mas complejo |
método de almacenamiento | texto | texto | binario |
guardar tamaño | grande | generalmente | Pequeño |
Velocidad de resolución | lento | generalmente | rápido |
ayuda de idioma | muchos | muchos | C/java/py |
Fácil de desarrollar | problema | respuesta corta | respuesta corta |
2. Serialización multiplataforma
Tengo entendido que la serialización es multiplataforma, las diferentes plataformas deben comunicarse entre sí y la serialización de objetos debe seguir reglas mutuas;
En general, las cosas multiplataforma obviamente necesitan una cantidad intermedia para filtrar, como Java multiplataforma, necesita un archivo de clase que sea equivalente a una plantilla, y Thrift rpc multiplataforma, necesita definir un archivo de formato .thrift; de manera similar, nuestro ProtoBuf es una herramienta de secuencia multiplataforma también es necesaria para definir.proto
3. Instalar
Soy la versión correspondiente de descarga directa probada en Windowshttps://github.com/protocolbuffers/protobuf/releases/tag/v21.4
Después de instalar la variable de entorno y ejecutar la información de la versión, significa OK
C:\Users\sff>protoc --version
libprotoc 2.5.0
4. Plantilla de aprendizaje
tipo de estudio
https://developers.google.cn/protocol-buffers/docs/proto
// 声明语法开头
syntax = "proto2";
//避免在 Protocol Buffers 名称空间以及非 Java 语言中的名称冲突。
package tutorial;
option java_multiple_files = true;
// java 对应的包和类
option java_package = "com.example.tutorial.protos";
//。如果你没有java_outer_classname明确给出a,它将通过将文件名转换为大写驼峰式来生成
option java_outer_classname = "AddressBookProtos";
message Person {
//标准的简单数据类型可用作字段类型 optional: 该字段可以设置也可以不设置 required:必须提供该字段的值,否则该消息将被视为“未初始化”
// repeated:该字段可以重复任意次数 required字段是非常不受欢迎的
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
Generar código java (también puede generar código en otros idiomas)
protoc addressbook.proto --java_out=D:\Resource\FrameMiddleware\proto\template
método de mensaje estándar
Cada clase de mensaje y constructor también contiene una serie de otros métodos que le permiten inspeccionar o manipular el mensaje completo, que incluyen:
isInitialized()
: Comprueba si todos los campos obligatorios están configurados.toString()
: Devuelve una representación legible por humanos del mensaje, especialmente útil para la depuración.mergeFrom(Message other)
: (solo constructores) Combina el contenido deother
en este mensaje, sobrescribe campos escalares únicos, combina campos compuestos y concatena campos repetidos.clear()
: (solo constructores) Borra todos los campos de nuevo a un estado vacío.
Estos métodos implementan Message
la interfaz compartida por todos los mensajes y constructores de Java. Message.Builder
Consulte la documentación completa de la APIMessage
para obtener más información .
análisis y serialización
Finalmente, cada clase de Protocol Buffers tiene métodos para escribir y leer mensajes del tipo que elija utilizando el formato binario de Protocol Buffers. Éstas incluyen:
byte[] toByteArray();
: serializa un mensaje y devuelve una matriz de bytes que contiene sus bytes sin formato.static Person parseFrom(byte[] data);
: analiza un mensaje de la matriz de bytes dada.void writeTo(OutputStream output);
: serialice el mensaje y escríbalo en elOutputStream
.static Person parseFrom(InputStream input);
: Leer y analizar desdeInputStream
.
5. prueba
Importación de código generado agregar maven
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.30.2</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.30.2</version>
</dependency>
<!-- 用于对比测试-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
codigo de prueba java
public class Main {
public static void main(String[] args) {
Person build = Person.newBuilder().setEmail("aaaaa").setName("zhangsan").setId(10).build();
System.out.println(build);
byte[] bytes = build.toByteArray();
System.out.println("bp size =" + bytes.length + "B");
PersonB personB = new PersonB("aaaaa", "zhangsan", 10);
byte[] bytes1 = JSONObject.toJSONString(personB).getBytes();
System.out.println(JSONObject.toJSONString(personB));
System.out.println("fastjson size =" + bytes1.length + "B");
}
}
resultado
name: "zhangsan"
id: 10
email: "aaaaa"
bp size =19B
{
"email":"aaaaa","id":10,"name":"zhangsan"}
fastjson size =43B
La prueba real es la mitad de la diferencia, pero mi prueba es solo una prueba menos rigurosa. . . . .
6.Avro
En comparación con pb, Avro está escrito en Java, también es una herramienta de serialización entre idiomas, la rutina es casi la misma