gRPC для Go (Golang): библиотеки, примеры и практическое руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

gRPC для Go (Golang): библиотеки и примеры

gRPC — это высокопроизводительный фреймворк удалённого вызова процедур (RPC) от Google, основанный на HTTP/2 и Protocol Buffers (protobuf). Для языка Go существует официальная реализация grpc-go, которая позволяет создавать эффективные микросервисы с поддержкой двунаправленной потоковой передачи, TLS-шифрования и перехватчиков (interceptors). В этой статье вы найдёте полное описание инструментов, примеры сервера и клиента, а также практические рекомендации.

Основные библиотеки для gRPC в Go

  • google.golang.org/grpc — основная библиотека gRPC для Go. Включает серверную и клиентскую части, поддержку потоков, метаданных и балансировки.
  • google.golang.org/protobuf — пакет для работы с protobuf-сообщениями: компиляция, сериализация, десериализация.
  • github.com/golang/protobuf/protoc-gen-go — плагин для компилятора protoc, генерирующий Go-код из .proto файлов.
  • github.com/grpc-ecosystem/grpc-gateway — утилита для создания REST-прокси поверх gRPC (полезно для совместимости с браузерами).

Установка и настройка

Перед началом работы установите компилятор protobuf и плагины:

# Установка protoc (Linux/macOS)
sudo apt install protobuf-compiler  # Ubuntu/Debian
brew install protobuf              # macOS

# Установка плагинов для Go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

После установки обновите PATH, добавив $GOPATH/bin.

Определение сервиса через .proto файл

Создайте файл hello.proto:

syntax = "proto3";

package hello;

option go_package = "example.com/grpc-demo/hello";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply);
    rpc SayHelloStream (HelloRequest) returns (stream HelloReply);
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

Сгенерируйте Go-код командой:

protoc --go_out=. --go-grpc_out=. hello.proto

Появятся файлы hello.pb.go (сообщения) и hello_grpc.pb.go (сервис).

Пример сервера на Go

package main

import (
    "log"
    "net"

    pb "example.com/grpc-demo/hello"
    "google.golang.org/grpc"
)

type server struct {
    pb.UnimplementedGreeterServer
}

func (s *server) SayHello(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error {
    // Обычный RPC
    return stream.Send(&pb.HelloReply{Message: "Hello, " + req.Name})
}

func (s *server) SayHelloStream(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error {
    // Потоковый ответ
    for i := 0; i < 5; i++ {
        if err := stream.Send(&pb.HelloReply{Message: "Hello " + req.Name + " #" + string(rune(i))}); err != nil {
            return err
        }
    }
    return nil
}

func main() {
    lis, _ := net.Listen("tcp", ":50051")
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    log.Println("Server listening on :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("Failed to serve: %v", err)
    }
}

Пример клиента на Go

package main

import (
    "context"
    "log"
    "time"

    pb "example.com/grpc-demo/hello"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    client := pb.NewGreeterClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    // Обычный вызов
    resp, err := client.SayHello(ctx, &pb.HelloRequest{Name: "Alice"})
    if err != nil {
        log.Fatalf("Error: %v", err)
    }
    log.Printf("Response: %s", resp.Message)

    // Потоковый вызов
    stream, err := client                    

Рекомендаций