Что такое gRPC?

«Что такое gRPC?» — вопрос из категории Сети, который задают на 22% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

gRPC — это высокопроизводительный фреймворк для удаленного вызова процедур (RPC) с открытым исходным кодом, разработанный Google. Он использует HTTP/2 в качестве транспортного протокола и Protocol Buffers (protobuf) в качестве языка описания интерфейсов и формата сериализации данных.

Ключевые особенности:

  • Языковая независимость: Клиент и сервер могут быть написаны на разных языках (Java, Go, Python, C++, C#, Node.js и др.).
  • Эффективность: Бинарный протокол protobuf обеспечивает компактную сериализацию и высокую скорость по сравнению с текстовыми форматами (например, JSON).
  • Потоковая передача: Поддерживает четыре модели взаимодействия: унарный (один запрос — один ответ), поток с сервера, поток с клиента и двунаправленный поток.
  • Встроенные функции: Поддержка аутентификации, сжатия, таймаутов, отмены вызовов и балансировки нагрузки.

Типичный рабочий процесс:

  1. Определение сервиса: Создается файл .proto с описанием сервиса (методы) и структур сообщений.
  2. Генерация кода: Компилятор protoc генерирует клиентский и серверный код-заглушки (stubs) для выбранного языка.
  3. Реализация: Разработчик реализует бизнес-логику на сервере и использует сгенерированный код на клиенте.

Пример (Java):

1. Определение сервиса (greeter.proto):

syntax = "proto3";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

2. Серверная реализация:

public class GreeterImpl extends GreeterGrpc.GreeterImplBase {
  @Override
  public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
    HelloReply reply = HelloReply.newBuilder()
        .setMessage("Hello " + req.getName())
        .build();
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
  }
}

3. Клиентский вызов:

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
    .usePlaintext() // Для простоты (в продакшене используйте TLS)
    .build();

GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);
HelloReply reply = stub.sayHello(
    HelloRequest.newBuilder().setName("World").build()
);
System.out.println(reply.getMessage()); // "Hello World"
channel.shutdown();

Основные сценарии использования: коммуникация между микросервисами, мобильные клиенты и бэкенд, системы, где критичны низкая задержка и высокая пропускная способность.