Introduksjon til gRPC

1. Introduksjon

gRPC er et RPC-rammeverk med høy ytelse og åpen kildekode som opprinnelig ble utviklet av Google. Det hjelper med å eliminere kokerplatekoden og hjelper til med å koble polyglottjenester i og på tvers av datasentre.

2. Oversikt

Rammeverket er basert på en klientservermodell av eksterne prosedyreanrop. En klientapplikasjon kan direkte kalle metoder på en serverapplikasjon som om det var et lokalt objekt.

Denne artikkelen vil bruke følgende trinn for å opprette et typisk klient-serverprogram ved hjelp av gRPC:

  1. Definere en tjeneste i en .proto fil
  2. Generer server- og klientkode ved hjelp av protokollbufferkompilatoren
  3. Opprett serverapplikasjonen, implementer de genererte tjenestegrensesnittene og gyt gRPC-serveren
  4. Opprett klientapplikasjonen, ring RPC-samtaler ved hjelp av genererte stubber

La oss definere en enkel HelloService som returnerer hilsener i bytte mot for- og etternavnet.

3. Maven-avhengigheter

La oss legge til avhengigheter grpc-netty, grpc-protobuf og grpc-stub:

 io.grpc grpc-netty 1.16.1 io.grpc grpc-protobuf 1.16.1 io.grpc grpc-stub 1.16.1 

4. Definere tjenesten

Vi starter med å definere en tjeneste, spesifisere metoder som kan kalles eksternt sammen med parametrene og returtypene.

Dette gjøres i .proto filen ved hjelp av protokollbufferne. De brukes også til å beskrive strukturen til nyttelastmeldingene.

4.1. Grunnleggende konfigurasjoner

La oss lage en HelloService.proto filen for eksemplet vårt HelloService. Vi starter med å legge til noen grunnleggende konfigurasjonsdetaljer:

syntaks = "proto3"; alternativet java_multiple_files = true; pakke org.baeldung.grpc;

Den første linjen forteller kompilatoren hvilken syntaks som brukes i denne filen. Som standard genererer kompilatoren all Java-koden i en enkelt Java-fil. Den andre linjen overstyrer denne innstillingen, og alt blir generert i individuelle filer.

Til slutt spesifiserer vi pakken vi vil bruke for våre genererte Java-klasser.

4.2. Definere meldingsstrukturen

Deretter definerer vi meldingen:

melding HelloRequest {string firstName = 1; streng etternavn = 2; }

Dette definerer nyttelasten for forespørselen. Her defineres hvert attributt som går inn i meldingen sammen med typen.

Et unikt nummer må tildeles hvert attributt, kalt som taggen. Denne koden brukes av protokollbufferen til å representere attributtet i stedet for å bruke attributtnavnet.

Så i motsetning til JSON hvor vi ville passere attributtnavn fornavn hver eneste gang ville protokollbuffer bruke tallet 1 til å representere fornavn. Svarets nyttelastdefinisjon er lik forespørselen.

Merk at vi kan bruke den samme taggen på tvers av flere meldingstyper:

melding HelloResponse {strenghilsen = 1; }

4.3. Definere servicekontrakten

Til slutt, la oss definere tjenestekontrakten. For vår HelloService vi definerer en Hallo() operasjon:

tjenesten HelloService {rpc hei (HelloRequest) returnerer (HelloResponse); }

De Hallo() operasjonen godtar en unary forespørsel og returnerer en unary respons. gRPC støtter også streaming ved å prefiks strøm nøkkelord til forespørselen og svaret.

5. Generere koden

Nå passerer vi HelloService.proto fil til protokollbufferkompilatoren protoc for å generere Java-filer. Det er flere måter å utløse dette på.

5.1. Bruke Protocol Buffer Compiler

Først trenger vi Protocol Buffer Compiler. Vi kan velge mellom mange forhåndskompilerte binærfiler tilgjengelig her.

I tillegg må vi skaffe gRPC Java Codegen Plugin.

Til slutt kan vi bruke følgende kommando for å generere koden:

protoc --plugin = protoc-gen-grpc-java = $ PATH_TO_PLUGIN -I = $ SRC_DIR --java_out = $ DST_DIR --grpc-java_out = $ DST_DIR $ SRC_DIR / HelloService.proto

5.2. Bruker Maven Plugin

Som utvikler vil du at kodegenerering skal være tett integrert med ditt byggesystem. gRPC gir en protobuf-maven-plugin for Maven-byggesystemet:

   kr.motd.maven os-maven-plugin 1.6.1 org.xolstice.maven.plugins protobuf-maven-plugin 0.6.1 com.google.protobuf: protoc: 3.3.0: exe: $ {os.detected.classifier} grpc-java io.grpc: protoc-gen-grpc-java: 1.4.0: exe: $ {os.detected.classifier} kompiler kompil-tilpasset 

Os-maven-plugin-utvidelsen / plugin genererer forskjellige nyttige plattformavhengige prosjektegenskaper som $ {os.detected.classifier}

6. Opprette serveren

Uansett hvilken metode du bruker for kodegenerering, genereres følgende nøkkelfiler:

  • HelloRequest.java - inneholder HelloRequest type definisjon
  • HelloResponse.javadette inneholder HelleResponse type definisjon
  • HelloServiceImplBase.javadette inneholder den abstrakte klassen HelloServiceImplBase som gir en implementering av alle operasjonene vi definerte i tjenestegrensesnittet

6.1. Overstyring av servicebaseklassen

De standard implementering av abstraktklassen HelloServiceImplBase er å kaste unntak for kjøretidio.grpc.StatusRuntimeException sier at metoden er uimplementert.

Vi skal utvide denne klassen og overstyre Hallo() metoden nevnt i vår tjenestedefinisjon:

offentlig klasse HelloServiceImpl utvider HelloServiceImplBase {@Override public void hallo (HelloRequest-forespørsel, StreamObserver-responsObserver) {Stringhilsen = ny StringBuilder () .append ("Hello") .append (request.getFirstName ()) .append (""). legge til (request.getLastName ()) .toString (); HelloResponse respons = HelloResponse.newBuilder () .setGreeting (hilsen) .build (); responseObserver.onNext (respons); responseObserver.onCompleted (); }}

Hvis vi sammenligner signaturen til Hallo() med den vi skrev i HellService.proto fil, vil vi legge merke til at den ikke kommer tilbake Hallo svar. I stedet tar det det andre argumentet som StreamObserver, som er en responsobservatør, en tilbakekalling for serveren å ringe med sitt svar.

Denne måten klienten får et alternativ for å ringe et blokkeringsanrop eller et ikke-blokkerende anrop.

gRPC bruker byggere for å lage objekter. Vi bruker HelloResponse.newBuilder () og sett hilsensteksten for å bygge en HelloResponse gjenstand. Vi setter dette objektet til responseObserver's påNeste () metode for å sende den til klienten.

Til slutt må vi ringe påFullført () for å spesifisere at vi er ferdig med RPC, ellers blir forbindelsen hengt, og klienten vil bare vente på at mer informasjon kommer inn.

6.2. Kjører Grpc Server

Deretter må vi starte gRPC-serveren for å lytte etter innkommende forespørsler:

public class GrpcServer {public static void main (String [] args) {Server server = ServerBuilder .forPort (8080) .addService (new HelloServiceImpl ()). build (); server.start (); server.awaitTermination (); }}

Her bruker vi igjen byggherren til å opprette en gRPC-server på port 8080 og legge til HelloServiceImpl tjeneste som vi definerte. start() vil starte serveren. I vårt eksempel vil vi ringe awaitTermination () for å holde serveren i gang i forgrunnen og blokkere meldingen.

7. Opprette klienten

gRPC gir en kanalkonstruksjon som trekker ut de underliggende detaljene som tilkobling, tilkoblingsbasseng, lastbalansering, etc.

Vi oppretter en kanal ved hjelp av ManagedChannelBuilder. Her spesifiserer vi serveradressen og porten.

Vi bruker ren tekst uten kryptering:

public class GrpcClient {public static void main (String [] args) {ManagedChannel channel = ManagedChannelBuilder.forAddress ("localhost", 8080) .usePlaintext () .build (); HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub (kanal); HelloResponse helloResponse = stub.hello (HelloRequest.newBuilder () .setFirstName ("Baeldung") .setLastName ("gRPC") .build ()); channel.shutdown (); }}

Deretter må vi lage en stub som vi vil bruke til å ringe den faktiske eksterne samtalen til Hallo(). Stubben er den primære måten klienter samhandler med serveren på. Når du bruker automatisk genererte stubber, vil stubklassen ha konstruktører for å pakke inn kanalen.

Her bruker vi en blokkerende / synkron stubbe slik at RPC-samtalen venter på at serveren skal svare, og vil enten returnere et svar eller heve et unntak. Det er to andre typer stubber levert av gRPC, som letter ikke-blokkerende / asynkrone samtaler.

Endelig tid til å lage Hallo() RPC-samtale. Her passerer vi HelloRequest. Vi kan bruke de automatisk genererte setterne til å stille inn fornavn, etternavn attributter til HelloRequest gjenstand.

Vi får tilbake Hallo svar objektet returneres fra serveren.

8. Konklusjon

I denne veiledningen så vi hvordan vi kunne bruke gRPC for å lette utviklingen av kommunikasjon mellom to tjenester ved å fokusere på å definere tjenesten og la gRPC håndtere all kjeleplatekoden.

Som vanlig finner du kildene på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found