Что такое gRPC?

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

Ответ

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

Ключевые преимущества для C++ разработки:

  • Производительность: Бинарный протокол protobuf и мультиплексирование потоков в HTTP/2 обеспечивают низкую задержку и высокую пропускную способность.
  • Строгая типизация: Интерфейсы и структуры данных определяются в .proto-файлах, что исключает ошибки несоответствия типов между клиентом и сервером.
  • Поддержка потоковой передачи: Помимо простых запросов-ответов, поддерживаются однонаправленные и двунаправленные потоки.

Пример: простой сервис на C++

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

    syntax = "proto3";
    package helloworld;
    
    service Greeter {
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    message HelloRequest {
      string name = 1;
    }
    
    message HelloReply {
      string message = 1;
    }
  2. Реализация сервера (упрощенно):

    #include <grpcpp/grpcpp.h>
    #include "greeter.grpc.pb.h"
    
    class GreeterServiceImpl final : public helloworld::Greeter::Service {
      grpc::Status SayHello(grpc::ServerContext* context,
                            const helloworld::HelloRequest* request,
                            helloworld::HelloReply* reply) override {
        std::string prefix("Hello, ");
        reply->set_message(prefix + request->name());
        return grpc::Status::OK;
      }
    };
    
    void RunServer() {
      std::string server_address("0.0.0.0:50051");
      GreeterServiceImpl service;
      grpc::ServerBuilder builder;
      builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
      builder.RegisterService(&service);
      std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
      server->Wait();
    }
  3. Клиентский вызов (упрощенно):

    auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
    std::unique_ptr<helloworld::Greeter::Stub> stub = helloworld::Greeter::NewStub(channel);
    
    helloworld::HelloRequest request;
    request.set_name("World");
    helloworld::HelloReply reply;
    grpc::ClientContext context;
    grpc::Status status = stub->SayHello(&context, request, &reply);
    if (status.ok()) {
      std::cout << reply.message() << std::endl;
    }

Типичное применение: микросервисные архитектуры, межпроцессное взаимодействие (IPC), клиент-серверные приложения, где важны низкая задержка и эффективность.