gRPC und seine Rolle bei der Kommunikation in Microservices

gRPC (gRPC Remote Procedure Calls) ist ein modernes, Open-Source, leistungsstarkes RPC (Remote Procedure Call) Framework, das von Google entwickelt wurde. Es ist darauf ausgelegt, die effiziente Kommunikation zwischen verteilten Systemen zu erleichtern und eignet sich daher besonders gut für Mikroservice-Architekturen. Hier ist eine Erklärung von gRPC und seiner Rolle in der Kommunikation von Mikroservices:

Was ist gRPC?

gRPC ist ein Protokoll, das es Client- und Serveranwendungen ermöglicht, transparent zu kommunizieren, was den Aufbau verteilter Systeme erleichtert. Es verwendet HTTP/2 für den Transport, Protocol Buffers (Protobuf) als seine Schnittstellendefinitionssprache (IDL) und bietet Funktionen wie Authentifizierung, Lastenausgleich und mehr. 

Hier sind einige Eigenschaften von gRPC:

  1. Sprachenunabhängig. gRPC unterstützt mehrere Programmiersprachen, darunter Java, Python, Go, C++ und mehr.
  2. Effiziente Kommunikation. Es verwendet die binäre Serialisierung mit Protobuf, die schneller und kompakter als textbasierte Formate wie JSON ist.
  3. Basierend auf HTTP/2. gRPC nutzt HTTP/2 und ermöglicht Funktionen wie Multiplexing, Streaming und verringerte Latenz.
  4. Stark typisiert. Dienste und Nachrichten werden mit Protobuf definiert, was die Typsicherheit gewährleistet und Fehler reduziert.
  5. Streaming-Unterstützung. gRPC unterstützt vier Arten von Streaming: einseitig, serverseitig, clientseitig und bidirektional.

Wie gRPC funktioniert

1. Definieren von Diensten und Nachrichten

Mit Protobuf definieren Sie die Service-Schnittstelle (Methoden) und die Struktur der auszutauschenden Nachrichten.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

2. Code generieren

Der Protobuf-Compiler (protoc) generiert Client- und Servercode in Ihrer gewählten Programmiersprache.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3. Server implementieren

Implementieren Sie die serverseitige Logik für den definierten Dienst.

4. Client erstellen

Verwenden Sie den generierten Clientcode, um die Servermethoden aufzurufen.

Rolle von gRPC in der Kommunikation zwischen Microservices

Microservices-Architekturen umfassen die Aufteilung von Anwendungen in kleinere, unabhängige Dienste, die über das Netzwerk kommunizieren. gRPC spielt in diesem Kontext aufgrund seiner Effizienz und Flexibilität eine entscheidende Rolle.

1. Hohe Leistung

  • gRPC verwendet die binäre Serialisierung mit Protobuf, die schneller und kompakter ist als textbasierte Formate wie JSON oder XML.
  • HTTP/2 reduziert die Latenz und verbessert die Durchsatzleistung, indem Multiplexing und Header-Komprimierung ermöglicht werden.

2. Klare Vertragsdefinition

  • Protobuf erzwingt einen strengen Vertrag zwischen Diensten, was die Wahrscheinlichkeit von Kommunikationsfehlern verringert.
  • Änderungen an der Dienstdefinition können durch Versionierung verwaltet werden, um die Abwärtskompatibilität sicherzustellen.

3. Streaming-Funktionen

  • gRPC unterstützt bidirektionales Streaming, was es ideal für die Echtzeitkommunikation macht, wie z.B. Chat-Anwendungen oder Live-Datenströme.
  • Serverseitiges und clientseitiges Streaming ermöglichen eine effiziente Verarbeitung großer Datensätze oder kontinuierlicher Datenflüsse.

4. Interoperabilität

  • gRPC ist sprachunabhängig, was es Mikrodiensten ermöglicht, die in verschiedenen Sprachen geschrieben sind, nahtlos zu kommunizieren.
  • Dies ist besonders nützlich in polyglotten Mikrodienstumgebungen.

5. Eingebaute Funktionen

  • gRPC bietet integrierte Unterstützung für Funktionen wie Authentifizierung, Verschlüsselung (via TLS) und Lastverteilung, wodurch der Bedarf an zusätzlichen Bibliotheken oder Werkzeugen verringert wird.

6. Skalierbarkeit

  • Die leichte Natur und die effiziente Kommunikation von gRPC machen es geeignet für groß angelegte Mikrodienstbereitstellungen.
  • Es integriert sich gut mit Container-Orchestrierungsplattformen wie Kubernetes.

Anwendungsfälle für gRPC in Mikrodiensten

  1. Inter-Service-Kommunikation. gRPC ist ideal für die Kommunikation zwischen Mikrodiensten, insbesondere in leistungskritischen Szenarien.
  2. Echtzeitsysteme. Seine Streaming-Funktionen machen es geeignet für Echtzeitanwendungen wie Gaming, IoT oder Live-Analysen.
  3. Polyglotte Umgebungen. Wenn Mikrodienste in verschiedenen Sprachen geschrieben sind, sorgt gRPC für eine nahtlose Kommunikation.
  4. Cloud-native Anwendungen. gRPC integriert sich gut mit cloud-nativen Technologien wie Kubernetes und Service-Meshes (z.B. Istio).

Vorteile von gRPC

  • Effizienz. Binäre Serialisierung und HTTP/2 machen gRPC schneller und ressourcenschonender.
  • Typensicherheit. Protobuf gewährleistet starke Typisierung und reduziert Laufzeitfehler.
  • Unterstützung mehrerer Sprachen. Funktioniert über mehrere Programmiersprachen hinweg.
  • Streaming. Unterstützt fortschrittliche Streaming-Muster für die Echtzeitkommunikation.

Herausforderungen von gRPC

  • Komplexität. Die Einrichtung von gRPC kann komplexer sein als REST, da Protobuf-Definitionen und Code-Generierung erforderlich sind.
  • Werkzeuge. Das Debuggen und Testen von gRPC-Diensten kann im Vergleich zu REST schwieriger sein, da Tools wie Postman nicht nativ für gRPC konzipiert sind.
  • Browserunterstützung. gRPC wird in Browsern nicht nativ unterstützt, was Tools wie gRPC-Web für webbasierte Clients erforderlich macht.

Warum gRPC mit Spring Boot verwenden?

Spring Boot ist ein beliebtes Framework zum Erstellen von Java-Anwendungen, und die Kombination mit gRPC ermöglicht es Entwicklern, leistungsstarke, skalierbare und interoperable Dienste zu erstellen. Mit der Auto-Konfiguration und der Abhängigkeitsinjektion von Spring Boot wird die Integration von gRPC unkompliziert.

Schritte zum Erstellen der Anwendung

Wir werden einen einfachen gRPC-Dienst namens Greeter erstellen, der es einem Client ermöglicht, einen Namen an den Server zu senden und eine „Hallo, {name}!“-Antwort zu erhalten. So gehen wir vor:

  1. Definieren Sie den gRPC-Dienst mit Protocol Buffers.
  2. Generieren Sie Java-Klassen aus der .proto-Datei.
  3. Implementieren Sie den gRPC-Server in Spring Boot.
  4. Implementieren Sie den gRPC-Client in Spring Boot.
  5. Fügen Sie einen REST-Controller hinzu, um den gRPC-Client zu Testzwecken aufzurufen.
  6. Führen Sie die Anwendung aus und testen Sie die Kommunikation.

1. Definieren Sie den gRPC-Dienst (.proto-Datei)

Der erste Schritt besteht darin, den gRPC-Dienst mit Protocol Buffers zu definieren. Erstellen Sie eine Datei mit dem Namen greeter.proto im Verzeichnis src/main/proto:

ProtoBuf

 

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "GreeterProto";
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
  string name = 1;
}
message HelloResponse {
  string message = 1;
}

Diese Datei definiert:

  • Ein Greeter-Dienst mit einer SayHello-RPC-Methode.
  • Eine HelloRequest-Nachricht, die ein name-Feld enthält.
  • Eine HelloResponse-Nachricht, die ein message-Feld enthält.

2. Abhängigkeiten hinzufügen

Um gRPC mit Spring Boot zu verwenden, fügen Sie die folgenden Abhängigkeiten zu Ihrer pom.xml hinzu:

XML

 

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
<!-- Spring Boot Web for REST Controller -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- gRPC dependencies -->
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty-shaded</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>1.54.0</version>
    </dependency>
    <!-- Protobuf Java Format -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.22.2</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- Protobuf Compiler Plugin -->
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.6.1</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.0:exe:${os.detected.classifier}</pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Diese Abhängigkeiten umfassen:

  • Spring Boot Starter für die grundlegende Anwendungsstruktur.
  • Spring Boot Web zur Unterstützung von REST-Controllern.
  • gRPC-Bibliotheken für die Implementierung von Server und Client.
  • Protobuf für die Serialisierung und Deserialisierung.

3. Java-Klassen generieren

Führen Sie den folgenden Maven-Befehl aus, um Java-Klassen aus der .proto-Datei zu generieren:

Plain Text

 

mvn clean compile

Dies wird die GreeterGrpc und zugehörigen Klassen im Verzeichnis target/generated-sources generieren.

4. Implementieren Sie den gRPC-Server

Implementieren Sie als Nächstes den gRPC-Server in Spring Boot. Erstellen Sie eine Klasse mit dem Namen GreeterService:

Java

 

package com.example.grpc.server;

import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class GreeterService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver responseObserver) {
        String name = request.getName();
        String message = "Hello, " + name + "!";
        HelloResponse response = HelloResponse.newBuilder().setMessage(message).build();
        // Sende die Antwort
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

Diese Klasse erweitert das generierte GreeterGrpc.GreeterImplBase und implementiert die Methode sayHello, um eingehende Anfragen zu bearbeiten.

5. Implementieren Sie den gRPC-Client

Implementieren Sie nun den gRPC-Client in Spring Boot. Erstellen Sie eine Klasse mit dem Namen GreeterClient:

Java

 

package com.example.grpc.client;
import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Service;
@Service
public class GreeterClient {
    private final GreeterGrpc.GreeterBlockingStub blockingStub;
    public GreeterClient() {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
                .usePlaintext()
                .build();
        this.blockingStub = GreeterGrpc.newBlockingStub(channel);
    }
    public String sayHello(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloResponse response = blockingStub.sayHello(request);
        return response.getMessage();
    }
}

Dieser Client verbindet sich mit dem gRPC-Server und sendet eine Anfrage an die Methode SayHello.

6. Fügen Sie einen REST-Controller für Tests hinzu

Um es einfacher zu machen, den gRPC-Client zu testen, fügen wir einen REST-Controller hinzu, der einen Endpunkt öffnet, um den GreeterClient aufzurufen. Erstellen Sie eine Klasse mit dem Namen GreeterController:

Java

 

package com.example.grpc.controller;
import com.example.grpc.client.GreeterClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreeterController {

    private final GreeterClient greeterClient;

    @Autowired
    public GreeterController(GreeterClient greeterClient) {
        this.greeterClient = greeterClient;
    }

    @GetMapping("/greet")
    public String greet(@RequestParam String name) {
        return greeterClient.sayHello(name);
    }
}

Dieser Controller öffnet einen /greet-Endpunkt, der einen name-Parameter akzeptiert und die Antwort vom gRPC-Server zurückgibt.

7. Erstellen Sie die Spring Boot-Anwendung

Erstellen Sie schließlich eine Spring Boot-Anwendung, um den Server und den Client auszuführen:

Java

 

package com.example.grpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrpcApplication {
    public static void main(String[] args) {
        SpringApplication.run(GrpcApplication.class, args);
    }
}

8. Konfigurieren Sie den Server-Port

Fügen Sie die folgende Konfiguration zu application.properties hinzu:

Plain Text

 

# gRPC-Server-Port
grpc.server.port=9090

# Spring Boot-Server-Port
server.port=8080

9. Starten Sie die Anwendung

  1. Starten Sie die Spring Boot-Anwendung.
  2. Der gRPC-Server wird auf Port 9090 starten.
  3. Der REST-Controller wird auf Port 8080 verfügbar sein.

Sie können die Anwendung testen, indem Sie eine GET-Anfrage an den Endpunkt /greet senden:

Plain Text

 

curl http://localhost:8080/greet?name=World

Die Antwort wird sein:

Plain Text

 

"Hello, World!"

Die richtige gRPC-Bibliothek für Spring Boot auswählen

Beim Aufbau von Spring Boot-Anwendungen, die eine gRPC-Integration erfordern, stehen Entwickler oft vor der Wahl zwischen mehreren Bibliotheken. Die am häufigsten diskutierten Optionen sind net.devh.grpc, org.lognet.grpc und org.springframework.grpc

Jede dieser Bibliotheken hat ihre eigenen Stärken, Schwächen und Anwendungsfälle. Lassen Sie uns die Unterschiede zwischen diesen Bibliotheken, ihren Funktionen und welche Sie für Ihr Projekt verwenden sollten, erkunden.

1. net.devh.grpc (grpc-spring-boot-starter)

net.devh.grpc, auch bekannt als grpc-spring-boot-starter, ist eine weit verbreitete Bibliothek zur Integration von gRPC mit Spring Boot. Sie wird aktiv gepflegt und bietet eine robuste Funktionssammlung zum Aufbau von gRPC-Servern und -Clients in einer Spring Boot-Anwendung.

Hauptfunktionen

  • Auto-Konfiguration. Vereinfacht die Einrichtung von gRPC-Servern und -Clients.
  • Spring-Integration. Unterstützt Dependency Injection und andere Spring-Funktionen.
  • Spring Security. Integriert sich problemlos mit Spring Security für sichere Kommunikation.
  • Health-Checks. Bietet Health-Checks über Spring Boot Actuator.
  • Synchronisierte und asynchrone Kommunikation. Unterstützt beide Kommunikationsstile.

Warum es verwenden?

  • Aktive Wartung. Die Bibliothek wird aktiv gewartet und aktualisiert.
  • Umfassende Dokumentation. Gut dokumentiert mit einer großen Community zur Unterstützung.
  • Produktionsbereit. Weit verbreitet in Produktionsumgebungen.

Wann es verwenden?

  • Wenn Sie eine neue Spring Boot-Anwendung erstellen und eine zuverlässige, funktionsreiche gRPC-Integration benötigen.
  • Wenn Sie eine nahtlose Integration mit Spring Boot-Funktionen wie Dependency Injection, Sicherheit und Gesundheitsprüfungen wünschen.

2. org.lognet.grpc (grpc-spring-boot-starter)

org.lognet.grpc ist eine weitere Bibliothek zur Integration von gRPC mit Spring Boot. Sie wird jedoch weniger aktiv gewartet im Vergleich zu net.devh.grpc und bietet nicht einige der fortgeschrittenen Funktionen, die letztere bietet.

Hauptmerkmale

  • Grundlegende gRPC-Einrichtung. Bietet grundlegende Unterstützung für gRPC-Server und -Clients.
  • Spring Boot-Integration. Funktioniert mit Spring Boot, jedoch mit weniger Funktionen.

Warum es verwenden?

  • Historische Nutzung. Es war eine der frühen Bibliotheken für die gRPC- und Spring Boot-Integration.
  • Einfachheit. Geeignet für einfache Anwendungsfälle.

Wann es verwenden?

  • Wenn Sie an einem älteren Projekt arbeiten, das bereits diese Bibliothek verwendet.
  • Nicht empfohlen für neue Projekte aufgrund begrenzter Wartung und weniger Funktionen.

3. org.springframework.grpc (Spring gRPC)

org.springframework.grpc ist ein experimentelles oder von der Community getriebenes Projekt zur Integration von gRPC mit Spring. Es handelt sich nicht um ein offizielles Spring-Projekt und könnte nicht so ausgereift oder funktionsreich sein wie net.devh.grpc.

Hauptfunktionen

  • Grundlegende gRPC-Integration. Bietet grundlegende Unterstützung für gRPC-Server und -Clients.
  • Anpassung an das Spring-Ökosystem. Entwickelt, um eng mit dem Spring-Ökosystem zu harmonieren.

Warum verwenden?

  • Experimentelle Nutzung. Geeignet für Experimente oder die Mitarbeit am Projekt.
  • Anpassung an Spring. Wenn Sie lieber etwas verwenden möchten, das eng mit Spring harmoniert.

Wann verwenden?

  • Nur, wenn Sie das Projekt erkunden oder dazu beitragen.
  • Aufgrund seines experimentellen Charakters nicht für den Produktiveinsatz empfohlen.

Welches sollten Sie verwenden?

Für neue Projekte

Verwenden Sie net.devh.grpc (grpc-spring-boot-starter). Es ist die ausgereifteste, aktiv gepflegte und funktionsreichste Option zur Integration von gRPC mit Spring Boot. Die nahtlose Integration mit den Funktionen von Spring Boot macht es zur besten Wahl für neue Projekte.

Für bestehende Projekte

Wenn Sie bereits org.lognet.grpc verwenden, erwägen Sie die Migration zu net.devh.grpc für bessere Unterstützung und Funktionen. Während org.lognet.grpc für ältere Projekte funktionieren kann, fehlt es an aktivem Support und fortgeschrittenen Funktionen von net.devh.grpc.

Zur experimentellen Verwendung

Wenn Sie die Spring gRPC-Integration erkunden oder dazu beitragen, können Sie org.springframework.grpc in Betracht ziehen. Es wird jedoch aufgrund seines experimentellen Charakters nicht für den Produktiveinsatz empfohlen.

Wichtige Überlegungen

  • Community-Support. net.devh.grpc verfügt über eine größere Community und bessere Dokumentation, was es einfacher macht, Hilfe und Ressourcen zu finden.
  • Produktionsbereitschaft. net.devh.grpc wird in Produktionsumgebungen weit verbreitet eingesetzt und gilt als stabil und zuverlässig.
  • Benutzerfreundlichkeit. net.devh.grpc bietet eine automatische Konfiguration und nahtlose Integration mit Spring Boot, was die Komplexität der Einrichtung reduziert.

Schlussfolgerung

gRPC ist ein leistungsstolles Tool für die Kommunikation zwischen Mikroservices, das hohe Leistung, starke Typisierung und erweiterte Funktionen wie Streaming bietet. Obwohl es im Vergleich zu REST mehr anfängliche Einrichtung erfordert, machen seine Effizienz und Skalierbarkeit es zu einer ausgezeichneten Wahl für moderne, verteilte Systeme.

Mit der zunehmenden Komplexität von Microservices-Architekturen spielt gRPC eine immer wichtigere Rolle bei der nahtlosen Kommunikation zwischen Diensten. In diesem Artikel haben wir eine einfache gRPC-Client- und Serveranwendung mit Spring Boot 3 erstellt, einen gRPC-Dienst mit Protocol Buffers definiert, Java-Klassen generiert, den Server und Client implementiert und einen REST-Controller für einfaches Testen hinzugefügt. Dieses Beispiel zeigt die Leistungsfähigkeit und Einfachheit von gRPC beim Aufbau leistungsstarker, skalierbarer und interoperabler Dienste. Sie können es weiter mit komplexeren Diensten, Streaming oder Fehlerbehandlung erweitern. Viel Spaß beim Programmieren!

GitHub-Repo: grpc-client-and-server-with-spring-boot.

Source:
https://dzone.com/articles/understanding-grpc-and-its-role-in-microservices-c