gRPC für Go (Golang): Bibliotheken, Beispiele und Anleitung

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

gRPC für Go (Golang): Bibliotheken und Beispiele

Was ist gRPC und warum wird es in Go verwendet?

gRPC ist ein leistungsstarkes Framework für entfernte Prozeduraufrufe (RPC), das von Google entwickelt wurde. Es nutzt Protocol Buffers (protobuf) zur Datenserialisierung und HTTP/2 als Transportprotokoll. In der Go-Ökosystem hat sich gRPC als Standard für den Aufbau von Microservices-Architekturen etabliert, dank:

  • Hoher Leistung (binäres Protokoll, HTTP/2-Multiplexing)
  • Starker Typisierung (generierter Go-Code)
  • Unterstützung von Streaming (Client, Server und bidirektional)
  • Integrierter Authentifizierung und Lastverteilung

In diesem Artikel betrachten wir die wichtigsten Bibliotheken, Tools und erstellen ein vollständiges Beispiel für einen Server und Client in Golang.

Erforderliche Bibliotheken und Tools

Für die Arbeit mit gRPC in Go benötigen Sie:

  • google.golang.org/grpc — die Hauptbibliothek für gRPC in Go
  • google.golang.org/protobuf — für die Arbeit mit Protocol Buffers
  • protoc — der Compiler für .proto-Dateien
  • protoc-gen-go — Plugin zur Generierung von Go-Code aus .proto
  • protoc-gen-go-grpc — Plugin zur Generierung von gRPC-Server-/Client-Code

Installation der Tools

# Installation von protoc (Linux/macOS)
sudo apt install protobuf-compiler  # oder brew install protobuf

# Installation der Go-Plugins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

# Überprüfung
protoc --version
protoc-gen-go --version

Erstellen einer .proto-Datei

Beginnen wir mit der Definition des Dienstes und der Nachrichten in der Datei hello.proto:

syntax = "proto3";

package hello;

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

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

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Generierung von Go-Code

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

Nach der Ausführung erscheinen zwei Dateien:

  • hello.pb.go — Nachrichtenstrukturen
  • hello_grpc.pb.go — Server- und Client-Schnittstellen

Implementierung eines gRPC-Servers in Go

Erstellen wir die Datei server.go:

package main

import (
    "context"
    "log"
    "net"

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

type server struct {
    pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
    log.Printf("Empfangen: %v", req.GetName())
    return &pb.HelloReply{Message: "Hallo, " + req.GetName()}, nil
}

func (s *server) SayHelloStream(req *pb.HelloRequest, stream pb.Greeter_SayHelloStreamServer) error {
    for i := 0; i < 5; i++ {
        if err := stream.Send(&pb.HelloReply{
            Message: "Hallo " + req.GetName() + " - " + fmt.Sprint(i),
        }); err != nil {
            return err
        }
    }
    return nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("Fehler beim Lauschen: %v", err)
    }

    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})

    log.Println("Server lauscht auf :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("Fehler beim Bereitstellen: %v", err)
    }
}

Implementierung eines gRPC-Clients in Go

Erstellen wir die Datei client.go:

package main

import (
    "context"
    "log"
    "time"

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

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

    client := pb.NewGreeterClient(conn)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    reply, err := client.SayHello(ctx, &pb.HelloRequest{Name: "Welt"})
    if err != nil {
        log.Fatalf("Fehler beim Aufruf: %v", err)
    }
    log.Printf("Antwort: %s", reply.GetMessage())
}

Empfehlungen