gRPC en de rol ervan in de communicatie tussen microservices

gRPC (gRPC Remote Procedure Calls) is een modern, open-source, hoog-presterend RPC (Remote Procedure Call) framework ontwikkeld door Google. Het is ontworpen om efficiënte communicatie tussen gedistribueerde systemen te vergemakkelijken, waardoor het bijzonder geschikt is voor microservices-architecturen. Hieronder volgt een uitleg van gRPC en de rol ervan in microservicescommunicatie:

Wat is gRPC?

gRPC is een protocol dat client- en serverapplicaties in staat stelt om transparant te communiceren, waardoor het eenvoudiger wordt om gedistribueerde systemen te bouwen. Het maakt gebruik van HTTP/2 voor transport, Protocol Buffers (Protobuf) als interface-definitietaal (IDL) en biedt functies zoals authenticatie, load balancing en meer.

Hier zijn enkele kenmerken van gRPC:

  1. Taal-onafhankelijk. gRPC ondersteunt meerdere programmeertalen, waaronder Java, Python, Go, C++ en meer.
  2. Efficiënte communicatie. Het gebruikt binaire serialisatie met Protobuf, wat sneller en compacter is dan tekstgebaseerde indelingen zoals JSON.
  3. Gebaseerd op HTTP/2. gRPC maakt gebruik van HTTP/2, waardoor functies zoals multiplexing, streaming en verminderde latentie mogelijk zijn.
  4. Sterk getypeerd. Diensten en berichten worden gedefinieerd met Protobuf, wat typeveiligheid waarborgt en fouten vermindert.
  5. Streamingondersteuning. gRPC ondersteunt vier soorten streaming: unair, server-streaming, client-streaming en bidirectionele streaming.

Hoe gRPC werkt

1. Definieer Services en Berichten

Met Protobuf definieer je de service-interface (methoden) en de structuur van de berichten die worden uitgewisseld.

ProtoBuf

 

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

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

2. Genereer Code

De Protobuf-compiler (protoc) genereert client- en servercode in de door jou gekozen programmeertaal.

ProtoBuf

 

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

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3. Implementeer Server

Implementeer de server-side logica voor de gedefinieerde service.

4. Maak Client

Gebruik de gegenereerde clientcode om de servermethoden aan te roepen.

Rol van gRPC in Microservices-communicatie

Microservices-architecturen houden in dat toepassingen worden opgesplitst in kleinere, onafhankelijke services die via het netwerk communiceren. gRPC speelt een cruciale rol in deze context vanwege zijn efficiëntie en flexibiliteit.

1. Hoge Prestaties

  • gRPC gebruikt binaire serialisatie met Protobuf, wat sneller en compacter is dan op tekst gebaseerde formaten zoals JSON of XML.
  • HTTP/2 verlaagt de latentie en verbetert de doorvoer door multiplexing en headercompressie mogelijk te maken.

2. Sterke Contractdefinitie

  • Protobuf dwingt een strikt contract af tussen services, waardoor de kans op communicatiefouten wordt verkleind.
  • Wijzigingen in de service-definitie kunnen worden beheerd met versiebeheer, waardoor achterwaartse compatibiliteit wordt gegarandeerd.

3. Streamingmogelijkheden

  • gRPC ondersteunt bidirectionele streaming, waardoor het ideaal is voor real-time communicatie, zoals chatapplicaties of live gegevensfeeds.
  • Streaming aan de serverzijde en de clientzijde maken efficiënte verwerking van grote datasets of continue datastromen mogelijk.

4. Interoperabiliteit

  • gRPC is taalonafhankelijk, waardoor microservices geschreven in verschillende talen naadloos kunnen communiceren.
  • Dit is met name handig in polyglot-microservicesomgevingen.

5. Ingebouwde functies

  • gRPC biedt ingebouwde ondersteuning voor functies zoals authenticatie, versleuteling (via TLS) en load balancing, waardoor de noodzaak voor extra bibliotheken of tools wordt verminderd.

6. Schaalbaarheid

  • De lichtgewicht aard en efficiënte communicatie van gRPC maken het geschikt voor grootschalige implementaties van microservices.
  • Het integreert goed met containerorkestratieplatforms zoals Kubernetes.

Gebruiksscenario’s voor gRPC in Microservices

  1. Interne-servicecommunicatie. gRPC is ideaal voor communicatie tussen microservices, vooral in prestatiekritieke scenario’s.
  2. Realtime systemen. Dankzij de streamingmogelijkheden is het geschikt voor realtime toepassingen zoals gaming, IoT of live-analyse.
  3. Polyglote omgevingen. Wanneer microservices in verschillende talen zijn geschreven, zorgt gRPC voor naadloze communicatie.
  4. Cloud-native applicaties. gRPC integreert goed met cloud-native technologieën zoals Kubernetes en service meshes (bijv. Istio).

Voordelen van gRPC

  • Efficiëntie. Binaire serialisatie en HTTP/2 maken gRPC sneller en efficiënter qua bronnen.
  • Typeveiligheid. Protobuf zorgt voor sterke typen, waardoor runtime-fouten worden verminderd.
  • Ondersteuning voor meerdere talen. Werkt met meerdere programmeertalen.
  • Streaming. Ondersteunt geavanceerde streamingpatronen voor realtime communicatie.

Uitdagingen van gRPC

  • Complexiteit. Het opzetten van gRPC kan complexer zijn dan REST vanwege de noodzaak van Protobuf-definities en codegeneratie.
  • Tools. Het debuggen en testen van gRPC-services kan moeilijker zijn in vergelijking met REST, aangezien tools zoals Postman niet specifiek zijn ontworpen voor gRPC.
  • Browserondersteuning. gRPC wordt niet standaard ondersteund in browsers, waardoor tools zoals gRPC-Web nodig zijn voor op web gebaseerde clients.

Waarom gRPC gebruiken met Spring Boot?

Spring Boot is een populair framework voor het bouwen van Java-toepassingen, en in combinatie met gRPC kunnen ontwikkelaars hoogwaardige, schaalbare en interoperabele services maken. Met de automatische configuratie en afhankelijkheidsinjectie van Spring Boot wordt het integreren van gRPC eenvoudig.

Stappen om de toepassing te bouwen

We zullen een eenvoudige gRPC-service genaamd Greeter bouwen waarmee een client een naam naar de server kan sturen en een “Hallo, {naam}!”-reactie kan ontvangen. Zo gaan we te werk:

  1. Definieer de gRPC-service met behulp van Protocol Buffers.
  2. Genereer Java-klassen van het .proto-bestand.
  3. Implementeer de gRPC-server in Spring Boot.
  4. Implementeer de gRPC-client in Spring Boot.
  5. Voeg een REST-controller toe om de gRPC-client te activeren voor testdoeleinden.
  6. Voer de toepassing uit en test de communicatie.

1. Definieer de gRPC-service (.proto-bestand)

De eerste stap is om de gRPC-service te definiëren met behulp van Protocol Buffers. Maak een bestand genaamd greeter.proto in de src/main/proto-map:

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;
}

Dit bestand definieert:

  • Een Greeter-service met een SayHello-RPC-methode.
  • Een HelloRequest-bericht met een name-veld.
  • Een HelloResponse-bericht met een message-veld.

2. Voeg afhankelijkheden toe

Om gRPC te gebruiken met Spring Boot, voeg de volgende afhankelijkheden toe aan je pom.xml:

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>

Deze afhankelijkheden omvatten:

  • Spring Boot Starter voor basisopstelling van de toepassing.
  • Spring Boot Web voor ondersteuning van REST-controller.
  • gRPC-bibliotheken voor server- en clientimplementatie.
  • Protobuf voor serialisatie en deserialisatie.

3. Genereer Java-klassen

Voer het volgende Maven-commando uit om Java-klassen te genereren van het .proto-bestand:

Plain Text

 

mvn clean compile

Dit zal de GreeterGrpc en gerelateerde klassen genereren in de map target/generated-sources.

4. Implementeer de gRPC Server

Vervolgens, implementeer de gRPC-server in Spring Boot. Maak een klasse met de naam 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();
        // Stuur het antwoord
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

Deze klasse breidt de gegenereerde GreeterGrpc.GreeterImplBase uit en implementeert de methode sayHello om inkomende verzoeken te verwerken.

5. Implementeer de gRPC-client

Implementeer nu de gRPC-client in Spring Boot. Maak een klasse met de naam 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();
    }
}

Deze client maakt verbinding met de gRPC-server en stuurt een verzoek naar de methode SayHello.

6. Voeg een REST-controller toe voor testen

Om het testen van de gRPC-client gemakkelijker te maken, voegen we een REST-controller toe die een eindpunt blootstelt om de GreeterClient aan te roepen. Maak een klasse met de naam 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);
    }
}

Deze controller blootstelt een /greet eindpunt dat een name parameter accepteert en het antwoord van de gRPC-server teruggeeft.

7. Maak de Spring Boot Applicatie

Tenslotte, maak een Spring Boot applicatie om de server en client uit te voeren:

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. Configureer de Serverpoort

Voeg de volgende configuratie toe aan application.properties:

Plain Text

 

# gRPC serverpoort
grpc.server.port=9090

# Spring Boot serverpoort
server.port=8080

9. Start de Applicatie

  1. Start de Spring Boot applicatie.
  2. De gRPC-server zal starten op poort 9090.
  3. De REST-controller zal beschikbaar zijn op poort 8080.

Je kunt de applicatie testen door een GET-verzoek te sturen naar de /greet-eindpunt:

Plain Text

 

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

De respons zal zijn:

Plain Text

 

"Hello, World!"

Het Juiste gRPC-bibliotheek Kiezen voor Spring Boot

Bij het bouwen van Spring Boot-applicaties die gRPC-integratie vereisen, staan ontwikkelaars vaak voor de keuze tussen verschillende bibliotheken. De meest besproken opties zijn net.devh.grpc, org.lognet.grpc, en org.springframework.grpc.

Elk van deze bibliotheken heeft zijn eigen sterke en zwakke punten en gebruiksscenario’s. Laten we de verschillen tussen deze bibliotheken, hun functies, en welke je moet gebruiken voor jouw project verkennen.

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

net.devh.grpc, ook bekend als grpc-spring-boot-starter, is een veelgebruikte bibliotheek voor het integreren van gRPC met Spring Boot. Het wordt actief onderhouden en biedt een robuuste set functies voor het bouwen van gRPC-servers en clients in een Spring Boot-applicatie.

Belangrijkste Functies

  • Auto-configuratie. Vereenvoudigt de opzet van gRPC-servers en clients.
  • Spring-integratie. Ondersteunt dependency injection en andere Spring-functies.
  • Spring-beveiliging. Integreert eenvoudig met Spring Security voor veilige communicatie.
  • Gezondheidscontroles. Biedt gezondheidscontroles via Spring Boot Actuator.
  • Synchrone en asynchrone communicatie. Ondersteunt beide communicatiestijlen.

Waarom gebruiken?

  • Actief onderhoud. De bibliotheek wordt actief onderhouden en bijgewerkt.
  • Uitgebreide documentatie. Goed gedocumenteerd met een grote community voor ondersteuning.
  • Klaar voor productie. Breed gebruikt in productieomgevingen.

Wanneer te gebruiken?

  • Als je een nieuwe Spring Boot-toepassing bouwt en een betrouwbare, functierijke gRPC-integratie nodig hebt.
  • Als je naadloze integratie wilt met Spring Boot-functies zoals afhankelijkheidsinjectie, beveiliging en gezondheidscontroles.

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

org.lognet.grpc is een andere bibliotheek voor het integreren van gRPC met Spring Boot. Het wordt echter minder actief onderhouden in vergelijking met net.devh.grpc en mist enkele geavanceerde functies die door laatstgenoemde worden aangeboden.

Belangrijkste kenmerken

  • Basis gRPC-opstelling. Biedt basisondersteuning voor gRPC-servers en -clients.
  • Spring Boot-integratie. Werkt met Spring Boot maar met minder functies.

Waarom gebruiken?

  • Historisch gebruik. Het was een van de vroege bibliotheken voor gRPC- en Spring Boot-integratie.
  • Eenvoud. Geschikt voor eenvoudige use-cases.

Wanneer te gebruiken?

  • Als je werkt aan een ouder project dat al deze bibliotheek gebruikt.
  • Niet aanbevolen voor nieuwe projecten vanwege beperkt onderhoud en minder functies.

3. org.springframework.grpc (Spring gRPC)

org.springframework.grpc is een experimenteel of door de community gedreven initiatief om gRPC te integreren met Spring. Het is geen officieel Spring-project en is mogelijk niet zo volwassen of rijk aan functies als net.devh.grpc.

Belangrijkste kenmerken

  • Basis gRPC-integratie. Biedt basisondersteuning voor gRPC-servers en -clients.
  • Alignment met het Spring-ecosysteem. Ontworpen om nauw aan te sluiten bij het Spring-ecosysteem.

Waarom gebruiken?

  • Experimenteel gebruik. Geschikt voor experimenten of bijdragen aan het project.
  • Alignment met Spring. Als u liever iets gebruikt dat nauw aansluit bij Spring.

Wanneer te gebruiken?

  • Alleen als u het project verkent of eraan bijdraagt.
  • Niet aanbevolen voor productiegebruik vanwege zijn experimentele aard.

Welke moet u gebruiken?

Voor nieuwe projecten

Gebruik net.devh.grpc (grpc-spring-boot-starter). Het is de meest volwassen, actief onderhouden en rijk aan functies optie voor het integreren van gRPC met Spring Boot. De naadloze integratie met Spring Boot-functies maakt het de beste keuze voor nieuwe projecten.

Voor bestaande projecten

Als u al gebruikmaakt van org.lognet.grpc, overweeg dan de overstap naar net.devh.grpc voor betere ondersteuning en functies. Hoewel org.lognet.grpc kan werken voor oudere projecten, mist het de actieve onderhoud en geavanceerde functies van net.devh.grpc.

Voor Experimenteel Gebruik

Als u Spring gRPC-integratie verkent of bijdraagt, kunt u kijken naar org.springframework.grpc. Het wordt echter niet aanbevolen voor productiegebruik vanwege de experimentele aard ervan.

Belangrijke Overwegingen

  • Communityondersteuning. net.devh.grpc heeft een grotere community en betere documentatie, waardoor het gemakkelijker is om hulp en middelen te vinden.
  • Productiegereedheid. net.devh.grpc wordt veel gebruikt in productieomgevingen en wordt beschouwd als stabiel en betrouwbaar.
  • Gebruiksgemak. net.devh.grpc biedt automatische configuratie en naadloze integratie met Spring Boot, waardoor de complexiteit van de opstelling wordt verminderd.

Conclusie

gRPC is een krachtige tool voor communicatie tussen microservices, met hoge prestaties, sterke typen en geavanceerde functies zoals streaming. Hoewel het meer initiële opstelling vereist in vergelijking met REST, maken de efficiëntie en schaalbaarheid het een uitstekende keuze voor moderne, gedistribueerde systemen.

Naarmate microservices architecturen complexer worden, speelt gRPC een steeds belangrijkere rol bij het mogelijk maken van naadloze communicatie tussen services. In dit artikel hebben we een eenvoudige gRPC-client en serverapplicatie gebouwd met behulp van Spring Boot 3, waarbij we een gRPC-service hebben gedefinieerd met Protocol Buffers, Java-klassen hebben gegenereerd, de server en client hebben geïmplementeerd, en een REST-controller hebben toegevoegd voor eenvoudige tests. Dit voorbeeld toont de kracht en eenvoud van gRPC voor het bouwen van high-performance, schaalbare en interoperabele services. Je kunt het verder uitbreiden met complexere services, streaming of foutafhandeling. Veel codeplezier!

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

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