Что такое protobuf и как он используется в gRPC
Что проверяют
Писали ли вы на Go сервисы с кодогенерацией: знаете ли цепочку от .proto до собранного сервера, понимаете ли, чем сгенерированная структура отличается от обычной, и как в gRPC устроены отмена, ошибки и общие для всех методов слои.
Как отвечать
Protocol Buffers это схема плюс бинарный формат сериализации. Из файла .proto компилятор protoc с плагинами protoc-gen-go и protoc-gen-go-grpc порождает структуры сообщений, интерфейс сервера и типизированный клиент. Транспорт gRPC это HTTP/2, отсюда мультиплексирование и потоковые вызовы.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest { string name = 1; }Специфика Go, которую и хотят услышать:
Сгенерированная структура содержит внутреннее состояние, поэтому её не копируют по значению, а передают указателем; go vet такое копирование ловит. Сравнивать сообщения нужно через proto.Equal, а не через оператор равенства.
Реализация сервиса встраивает UnimplementedGreeterServer: новый метод в схеме тогда не ломает сборку. Первым аргументом каждого метода идёт context.Context, через него доезжают дедлайн и отмена вызова. Ошибки возвращают через status.Error с кодом из codes, иначе клиент получит невнятный Unknown вместо NotFound.
Логи, метрики, проверку токена выносят в интерсепторы, чтобы не дублировать в каждом методе. Соединение grpc.ClientConn создают один раз на процесс: оно потокобезопасно и само переподключается.
Где спотыкаются
Сравнивают сообщения оператором равенства или кладут их в map как значения. Внутреннее состояние делает такое сравнение неверным и иногда просто не компилируемым, а копия по значению приводит к трудноуловимым гонкам.
Ждут от proto3, что он отличит пустую строку от отсутствующего поля. Без optional или обёртки не отличит, и валидация вида «если имя не пустое» тихо пропускает запросы, где поле забыли заполнить.
Создают новое соединение на каждый вызов и закрывают его следом. Это убивает весь смысл HTTP/2: теряются установленное соединение и мультиплексирование, растут задержки, а при нагрузке заканчиваются сокеты.