В последнее время я отвечал за разработку сервисов платформы функций. Первоначальная версия доступа к данным функций использовала JSON String. В то время рассматривалась возможность быстрой итерации онлайн. JSON — относительно простой и широко используемый формат обмена данными. Это простая структура данных и не требует производительности. Это осуществимо, когда она высока, но поскольку объем вызовов этой услуги увеличивается, а также требуется производительность, этот подход не осуществим. Основные возникающие проблемы заключаются в следующем:
- Строка JSON обрабатывается очень медленно и часто занимает десятки миллисекунд при большом объеме вызовов, что приводит к тайм-ауту вызова.
- Структура JSON занимает больше места для хранения без какого-либо сжатия, а передача по сети занимает относительно много времени.
- Проблемы с сборщиком мусора
Команда промежуточного программного обеспечения предложила использовать протокольный буфер. После исследования они решили использовать протокольный буфер для оптимизации услуг. Ниже приводится краткое введение в его использование, которое в основном включает три этапа:
- существует.protoОпределить формат данных в файле
- согласно с.protoфайл класса генерации файлов
- использовать
1. Определите формат данных
Создайте новый с.protoконец файла, например новыйmq_message.proto:
// 指定使用哪个版本的语法,需要在第一行指定
syntax = "proto3";
package example;
// 指定 java_package, 不指定就使用 package.生成的类会放到该package下
option java_package = "com.example.example";
// 生成的类名
option java_outer_classname = "MQMessageProtos";
message MQMessage {
// required 修饰的字段必须提供,否则 build 会抛 RuntimeException, parse 会抛 IOException. 后续扩展时 required 字段不可修改
// 声明一个枚举类型
enum OperationType {
UPDATE = 0;
DELETE = 1;
}
// 声明一个枚举类型的字段,等号后面的数字是标识数字
OperationType operationType = 1;
// 声明一个 string 类型的字段
string name = 2;
// 声明一个 Item 的 List
repeated Item items = 3;
}
message Item {
// 声明一个 string 类型的字段
string key = 1;
// 声明一个 map 类型字段
map<string, string> fields = 2;
}
- Сначала укажите версию синтаксиса,proto2а такжеproto3Есть некоторые отличия, за подробностями можно обратиться к официальной документации (может понадобиться трап,proto2, proto3), используемые в этой статьеproto3.
- package и java_package указывают пакет, в котором расположены сгенерированные классы Java, чтобы избежать конфликтов имен.
- java_outer_classname указывает сгенерированное имя класса, если не указано, оно будет сгенерировано на основе имени файла, например: my_proto.proto создаст класс MyProto.
- сообщение предназначено для определения формата данных.
- Один.protoВ файле может быть определено несколько сообщений
- Поля, определенные в сообщении, поддерживают строку, байт, логическое значение, карту, перечисление, числовые типы и пользовательские сообщения.
- После определения поля необходимо указать уникальный идентификационный номер.Эти числа используются для идентификации полей в сообщении в двоичном формате.После использования сообщения идентификационный номер не может быть изменен.(Числа 1-15 будут закодированы с один байт, больше 15 Число будет использовать больше байтов для кодирования, поэтому старайтесь оставить меньшее число для наиболее часто встречающегося поля.При указании идентификационного номера поля не обязательно соблюдать порядок.)
- Если вам нужно определить список, вы можете добавить повтор перед полем.
- Если вы уже использовали класс, сгенерированный сообщением, вы можете напрямую добавить поле, если хотите его добавить. Когда класс с новым полем анализирует старые данные, для нового поля будет установлено значение по умолчанию. старый класс анализирует новые данные, новому полю будет присвоено значение по умолчанию, новые поля игнорируются.
2. Согласно.protoфайл класса генерации файлов
четко определенный.protoСкомпилируйте с помощью компилятора буфера протокола после файла.protoфайл может быть. Вам необходимо установить компилятор буфера протокола локально, вы можете установить его непосредственно с помощью brew на Mac os: brew install protobuf Для других систем см.:официальная документацияПосле установки компилятора выполните команду компиляции:
protoc --java_out=./ ./mq_message.proto
--java_out указывает каталог, в котором находятся файлы, сгенерированные после компиляции, и, наконец, указывает файлы, которые вы хотите скомпилировать.
3. Используйте
Ниже приведен пример использования класса, сгенерированного из файла mq_message.proto выше:
public class TestPB {
public static void main(String[] args) {
MQMessageProtos.Item item1 = MQMessageProtos.Item.newBuilder()
.setKey("1")
.putFields("field1", "value1")
.putFields("field2", "value2")
.build();
MQMessageProtos.Item item2 = MQMessageProtos.Item.newBuilder()
.setKey("2")
.putFields("field3", "value3")
.putFields("field4", "value4")
.build();
MQMessageProtos.MQMessage mqMessage = MQMessageProtos.MQMessage.newBuilder()
.setName("testName")
.setOperationType(MQMessageProtos.MQMessage.OperationType.UPDATE)
.addItems(item1)
.addItems(item2)
.build();
byte[] byteArray = mqMessage.toByteArray();
try {
MQMessageProtos.MQMessage message = MQMessageProtos.MQMessage.parseFrom(byteArray);
System.out.println(message.getName());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
}
Наконец, добро пожаловать в мой личный блог:Чен Минджи