Más información sobre ProtoBuf
Cuando realizamos llamadas de comunicación de red, siempre necesitamos serializar los bloques de datos en la memoria en un formato que pueda transmitirse a través de la red. Una vez que se complete la transferencia, este formato se serializará y restaurará a nuestra estructura de datos deseada.
Por lo tanto, tenemos ciertos requisitos para este formato de datos utilizado para la transmisión de red intermedia. En primer lugar, debe describir con precisión el contenido de los datos y, en segundo lugar, queremos que sea lo más pequeño posible.
El formato más popular es XML (Lenguaje de Marcado Extensible). Dado que se puede utilizar para etiquetar datos y definir tipos de datos, los usuarios pueden definir su propio idioma para sus datos, lo que les permite estructurar datos dispares en un formato unificado.
Otro lenguaje con el que estamos familiarizados es JSON (Notación de objetos JavaScript). Aunque JSON carece de los atributos de etiqueta y otras descripciones que se encuentran en XML, su estructura jerárquica es lo suficientemente concisa y clara como para convertirlo en un formato de intercambio de datos preferido sobre XML.
JSON claramente ocupa menos espacio que XML para la misma cantidad de datos. Entonces, ¿dónde se ahorra el espacio? Por un lado, JSON utiliza caracteres más simples para definir la correlación entre datos; por otro lado, JSON reduce la descripción de los tipos de datos; ¿Pero dónde están los tipos de datos reducidos?
Tomando OpenFeign en Java como ejemplo, las definiciones de tipos que faltan en JSON se definen en la interfaz del programa. El formato JSON no documenta los tipos de datos cuando se serializan y deserializan tipos de datos específicos en serializadores y deserializadores a través de interfaces acordadas previamente. Esto reduce la cantidad de información durante la transmisión, permitiendo que los datos se compriman.
Sin embargo, dado que el tipo de datos no está definido, JSON es en realidad un flujo de texto durante la transmisión, entonces, ¿se puede comprimir aún más este método?
Combinando la discusión anterior, concluimos que hay una manera de escribir la implementación actual de ProtoBuf.
Podemos echar un vistazo a la definición y descripción oficial:
De manera similar, ProtoBuf es un método que admite serialización y deserialización, y tiene muchas ventajas:
> ProtoBuf es un método que admite serialización y deserialización. Y tiene muchas ventajas:
De hecho, ProtoBuf proporciona una forma común de describir datos, que es universal, al igual que JSON o XML.
A continuación, respondamos la pregunta planteada al principio de esta sección: ¿Cómo hace ProtoBuf para hacer JSON más pequeño? La respuesta es simple: proporciona más conocimientos previos para la serialización y deserialización de datos.
Este artículo no discutirá el principio de ProtoBuf demasiado profundamente, pero se puede explicar brevemente a través del cuadro ():
Los datos en ProtoBuf están organizados en orden y su La estructura general consta de varios campos, cada campo consta de Etiqueta-[Longitud]-Valor. Cada campo consta de etiqueta-[longitud]-valor. La longitud es opcional, y su presencia o ausencia viene determinada por el tipo de marcador. Esto significa que si es un tipo específico, como int64, entonces conocemos la longitud del Valor sin tener que depender de la Longitud para describir su espacio (esta es la misma idea que las listas comprimidas en redis).
Entonces, ¿a qué campo debería corresponder el campo? Esto está predefinido por los servidores y clientes de ProtoBuf durante la serialización y deserialización. Dado que el tipo y el orden de los campos se definen de antemano, no es necesario describir los campos en sí con nombres de campo ni posiciones de campo, sino que solo es necesario serializarlos utilizando el método de serialización binaria apropiado según el tipo de campo. y el valor del campo en sí se puede serializar para su transmisión.
Para resumir:
ProtoBuf predefine el nombre y el orden de los campos que se transferirán, por lo que solo la etiqueta de tipo y el valor binario de cada campo se registran en orden en la estructura de transferencia.
Aunque tanto lo anterior como oficialmente comparan ProtoBuf con XML o JSON. Sin embargo, dado que ProtoBuf en sí está serializado en binario, hacer la comparación desde la perspectiva de la relación de compresión parece un poco intimidante.
Los serializadores binarios correspondientes en Java son Kryo y Hessian, pero de hecho tanto Kryo como Hessian necesitan almacenar nombres de clases Java e información de campo. ProtoBuf solo requiere pares de datos Etiqueta-Longitud-Valor, y el Valor está especialmente codificado de manera específica, por lo que ocupa mucho menos espacio.
Kryo está optimizado para Java. Entonces, en términos de facilidad de uso, Kryo es más conveniente. Pero ProtoBuf es multiplataforma y, debido a que los campos se definen en orden, las interfaces definidas como ProtoBuf son compatibles con versiones anteriores (solo los campos se pueden agregar al revés), mientras que Kryo no tiene esta ventaja.
ProtoBuf es multilingüe. El primer paso para usar ProtoBuf es definir el archivo proto. Dado que las versiones de idioma de ProtoBuf 2 y 3 son diferentes, los formatos de definición también son diferentes. a la documentación oficial: /protocol -buffers /docs/proto3
Para el documento de definición de ProtoBuf 3, podemos definirlo de la siguiente manera:
La palabra clave del mensaje es el nombre del archivo por definición, y string e int32 están predeterminados. Tipo de campo, repetido describe un campo como uno que se puede repetir cualquier número de veces.
ProtoBuf define la estructura de archivos para transferir información a través de este formulario de archivo.
Sin embargo, como sabemos por la sección anterior, ProtoBuf transmite información a través de un conjunto de datos compuesto por Etiqueta-[Longitud]-Valor, entonces, ¿cómo se define el contenido en el archivo proto? objeto de transferencia?
ProtoBuf proporciona un protocolo generador para cada lenguaje que se puede utilizar para generar un conjunto de archivos java a partir de un archivo .proto. La demostración de sintaxis oficial correspondiente es
La información de referencia oficial del generador es /protocol-buffers/docs/reference/java-generated
El archivo java generado proporcionará las entidades y constructores de datos correspondientes documentación que respalde el uso posterior.
Cabe señalar que ProtoBuf es esencialmente un método de serialización, ya sea que se llame a través de OpenFeign de Spring Cloud o mediante grpc.
En este artículo hemos organizado el concepto de ProtoBuff sin entrar en todos los detalles para que puedas leerlo como una ciencia conceptual.