Открыть сервис

Proto2

Proto2 — это язык описания структур данных (IDL) и формат сериализации, разработанный компанией Google как часть системы Google Protocol Buffers. Он используется для определения структуры сообщений и их последующей кодировки в компактный бинарный вид для передачи по сети или хранения. Proto2 является предшественником более современного языка Proto3 и на протяжении длительного времени оставался стандартом для внутренней коммуникации в экосистеме Google.

История

Разработка Protocol Buffers началась в компании Google в начале 2000-х годов как внутренняя альтернатива XML для обмена данными между серверными приложениями. Основной целью было создание более быстрого и компактного формата, чем XML, который требовал значительных вычислительных ресурсов на парсинг. Первая версия (Proto1) использовалась внутри компании, но не была стандартизирована. В 2008 году Google выпустила открытую версию под названием Proto2, которая стала доступна для внешних разработчиков. В 2016 году появился Proto3 с упрощённым синтаксисом, однако Proto2 продолжает поддерживаться и использоваться в ряде крупных проектов, включая Apache Kafka (для совместимости) и некоторые внутренние системы Google.

Синтаксис и структура

Файл .proto в Proto2 начинается с объявления синтаксиса: syntax = "proto2";. Основой описания является сообщение (message), которое содержит поля. Каждое поле имеет три обязательных атрибута: тип, имя и номер. Номера полей используются для бинарной кодировки и должны быть уникальными в пределах сообщения.

Ключевым отличием Proto2 от Proto3 является наличие модификаторов required и optional. Поле required обязательно должно быть заполнено при сериализации, а optional может отсутствовать. В Proto3 все поля являются необязательными, а required был полностью исключён из синтаксиса. Также Proto2 поддерживает механизм extensions, позволяющий расширять сообщение извне, и группировку полей (group), которая впоследствии была признана устаревшей.

Пример определения

```protobuf syntax = "proto2";

message Person { required string name = 1; required int32 id = 2; optional string email = 3;

enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; }

message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; }

repeated PhoneNumber phones = 4; } ```

В этом примере показаны основные конструкции: перечисления (enum), вложенные сообщения, поля с типом repeated (массив) и значения по умолчанию.

Кодировка и сериализация

Proto2 использует бинарную кодировку на основе вариативной длины (varint). Целые числа до 2^32-1 кодируются одним байтом, если они меньше 128, и расширяются до пяти байт при больших значениях. Строки и байтовые массивы кодируются как длина (varint) + данные. Сообщение не содержит информации о тегах полей в текстовом виде, что делает его значительно компактнее JSON или XML.

Одним из преимуществ формата является обратная совместимость: добавление новых полей в сообщение не нарушает чтение старых данных, так как неизвестные поля просто пропускаются при десериализации. Это достигается за счёт строгой схемы номеров полей.

Генерация кода

Для работы с Proto2 используются компиляторы protoc, которые генерируют исходный код на языках программирования: C++, Java, Python, Go, C#, Ruby и других. Сгенерированный код предоставляет классы с методами доступа к полям, а также методами SerializeToString() и ParseFromString() для сериализации и десериализации.

Применение

Proto2 широко применяется в системах, где важна производительность и компактность данных. Основные области использования:

  • Микросервисная архитектура — для внутреннего обмена данными между сервисами (например, в gRPC, хотя gRPC по умолчанию использует Proto3).
  • Хранение конфигураций — бинарные конфигурационные файлы, которые не требуют ручного редактирования.
  • Системы обмена сообщениями — например, Apache Kafka использует Protocol Buffers для описания схем данных (хотя в новых версиях поддерживается и Proto3).
  • Мобильная разработка — для уменьшения размера передаваемых данных по сравнению с JSON.

Критика и ограничения

Основным недостатком Proto2 считается отсутствие встроенной поддержки карт (map), которая появилась только в Proto3. Также бинарный формат не является человекочитаемым, что затрудняет отладку. Механизм required полей вызывает критику: его использование приводит к невозможности чтения старых данных при изменении схемы, что нарушает принципы эволюционного проектирования. В ответ на это в Proto3 все поля стали необязательными.

Сравнение с Proto3

ХарактеристикаProto2Proto3
Синтаксисsyntax = "proto2"syntax = "proto3"
Модификаторыrequired, optional, repeatedтолько repeated (все поля optional)
Картыне поддерживаютсяподдерживаются
Значения по умолчаниюнастраиваются через [default = ...]фиксированные (0, пустая строка, false)
Расширения (extensions)поддерживаютсяисключены
Группы (group)поддерживаются (устарели)исключены

Интересные факты

  • Несмотря на выход Proto3, многие внутренние сервисы Google до сих пор используют Proto2 из-за огромного объёма унаследованного кода.
  • Формат сериализации Protocol Buffers используется не только для RPC, но и для хранения данных в распределённых базах данных, таких как Apache HBase и Cassandra (через соответствующие адаптеры).
  • Компилятор protoc поддерживает плагины, что позволяет генерировать код для кастомных языков или фреймворков.

Источники

  • Google Developers. Protocol Buffers Documentation.
  • Документация Apache Kafka по совместимости схем.
  • Официальный репозиторий protobuf на GitHub.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →