Bevezetés a gRPC-be
1. Bemutatkozás
A gRPC egy nagy teljesítményű, nyílt forráskódú RPC keretrendszer, amelyet eredetileg a Google fejlesztett ki. Segít a kazánlemez-kód kiküszöbölésében, és segít összekapcsolni a poliglot szolgáltatásokat az adatközpontokban és azok között.
2. Áttekintés
A keretrendszer a távoli eljáráshívások kliens-szerver modelljén alapszik. Az ügyfélalkalmazás közvetlenül meghívhatja a kiszolgálóalkalmazások metódusait, mintha helyi objektumok lennének.
Ez a cikk a következő lépéseket fogja használni egy tipikus kliens-kiszolgáló alkalmazás létrehozásához a gRPC segítségével:
- Adjon meg egy szolgáltatást a .proto fájl
- Létrehozza a kiszolgáló és az ügyfél kódját a protokollpuffer fordító segítségével
- Hozza létre a kiszolgálóalkalmazást, a létrehozott szolgáltatási felületek megvalósításával és a gRPC kiszolgáló létrehozásával
- Hozza létre az ügyfélalkalmazást, RPC hívásokat kezdeményezve generált csonkok felhasználásával
Határozzunk meg egy egyszerűt HelloService amely üdvözletet ad vissza az utó- és a vezetéknévért cserébe.
3. Maven-függőségek
Adjunk hozzá grpc-netty, grpc-protobuf és grpc-stub függőségeket:
io.grpc grpc-netty 1.16.1 io.grpc grpc-protobuf 1.16.1 io.grpc grpc-stub 1.16.1
4. A szolgáltatás meghatározása
Kezdjük egy szolgáltatás definiálásával, a távolról hívható módszerek meghatározása a paraméterekkel és a visszatérési típusokkal együtt.
Ez a .proto fájlokat a protokollpufferek segítségével. Ezeket használják a hasznos teher üzenetek felépítésének leírására is.
4.1. Alapkonfigurációk
Hozzunk létre egy HelloService.proto fájl a mintánkhoz HelloService. Kezdjük néhány alapvető konfigurációs részlet hozzáadásával:
szintaxis = "proto3"; opció java_multiple_files = true; org.baeldung.grpc csomag;
Az első sor megmondja a fordítónak, hogy milyen szintaxist használnak ebben a fájlban. Alapértelmezés szerint a fordító az összes Java kódot egyetlen Java fájlban generálja. A második sor felülírja ezt a beállítást, és minden egyes fájlokban lesz létrehozva.
Végül meghatározzuk azt a csomagot, amelyet a létrehozott Java osztályokhoz használni akarunk.
4.2. Az üzenet struktúrájának meghatározása
Ezután meghatározzuk az üzenetet:
üzenet HelloRequest {string firstName = 1; karakterlánc vezetéknév = 2; }
Ez meghatározza a kérelem hasznos terhelését. Itt minden, az üzenetbe kerülő attribútum meg van határozva a típusával együtt.
Minden attribútumhoz egyedi számot kell rendelni, amelyet címkének hívnak. Ezt a címkét használja a protokollpuffer az attribútum képviseletére az attribútum neve helyett.
Tehát, ellentétben a JSON-val, ahol átadnánk az attribútum nevét keresztnév minden egyes alkalommal a protokollpuffer az 1-es számot használja a képviselethez keresztnév. A válasz hasznos adatainak meghatározása hasonló a kéréshez.
Ne feledje, hogy ugyanazt a címkét több üzenettípusnál is használhatjuk:
üzenet HelloResponse {string greeting = 1; }
4.3. A szolgáltatási szerződés meghatározása
Végül határozzuk meg a szolgáltatási szerződést. A mi HelloService meghatározzuk a Helló() művelet:
szolgáltatás HelloService {rpc hello (HelloRequest) visszatér (HelloResponse); }
A Helló() a művelet elfogadja az unária kérést és visszajelzést ad vissza. A gRPC a streaminget is támogatja az előtagolással folyam kulcsszó a kéréshez és a válaszhoz.
5. A kód létrehozása
Most elhaladunk a HelloService.proto fájlt a protokollpuffer fordítóhoz protokoll a Java fájlok előállításához. Ennek kiváltására többféle módon van lehetőség.
5.1. A Protocol Buffer Compiler használatával
Először is szükségünk van a Protocol Buffer Compiler-re. Számos előre lefordított bináris közül választhatunk itt.
Ezenkívül meg kell szereznünk a gRPC Java Codegen beépülő modult.
Végül a következő paranccsal generálhatjuk a kódot:
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. A Maven beépülő modul használata
Fejlesztőként azt szeretné, ha a kódgenerálás szorosan integrálódna a build rendszerébe. A gRPC a protobuf-maven-plugin a Maven build rendszerhez:
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} fordítás compile-custom
Az os-maven-plugin kiterjesztés / bővítmény különféle hasznos platformfüggő projekt tulajdonságokat generál, például $ {os.detected.classifier}
6. A szerver létrehozása
Függetlenül attól, hogy melyik módszert használja a kódgeneráláshoz, a következő kulcsfájlok jönnek létre:
- HelloRequest.java - tartalmazza a HelloRequest típusmeghatározás
- HelloResponse.java – ez tartalmazza a HelleVálasz típusmeghatározás
- HelloServiceImplBase.java – ez tartalmazza az absztrakt osztályt HelloServiceImplBase amely biztosítja az összes olyan műveletet, amelyet a szolgáltatási felületen definiáltunk
6.1. A szolgáltatás alaposztályának felülírása
A az absztrakt osztály alapértelmezett megvalósítása HelloServiceImplBase futásidejű kivételio.grpc.StatusRuntimeException mondván, hogy a módszer nincs megvalósítva.
Kiterjesztjük ezt az osztályt és felülírjuk a Helló() szolgáltatás definíciónkban említett módszer:
public class HelloServiceImpl kiterjeszti a HelloServiceImplBase {@Orride public void hello (HelloRequest kérés, StreamObserver responseObserver) {String üdvözlet = new StringBuilder () .append ("Hello") .append (request.getFirstName ()) .append (""). addend (request.getLastName ()) .toString (); HelloResponse response = HelloResponse.newBuilder () .setGreeting (üdvözlet) .build (); responseObserver.onNext (válasz); responseObserver.onCompleted (); }}
Ha összehasonlítjuk az aláírását Helló() azzal, amelyet a HellService.proto fájlt, észrevesszük, hogy nem tér vissza HelloResponse. Ehelyett a második érvet a következőként veszi fel StreamObserver, amely válaszmegfigyelő, visszahívás a kiszolgáló számára, hogy felhívja a válaszát.
Ily módon az ügyfél lehetőséget kap blokkoló vagy nem blokkoló hívás kezdeményezésére.
A gRPC építőket használ objektumok létrehozásához. Használunk HelloResponse.newBuilder () és állítsa az üdvözlő szöveget a HelloResponse tárgy. Ezt az objektumot a responseObserver-re állítottuk onNext () módszerrel elküldheti az ügyfélnek.
Végül hívnunk kell onCompleted () annak megadásához, hogy befejeztük az RPC-vel való foglalkozást, különben a kapcsolat felfüggesztésre kerül, és az ügyfél csak arra vár, hogy további információk érkezzenek.
6.2. A Grpc kiszolgáló futtatása
Ezután el kell indítanunk a gRPC szervert a beérkező kérések figyelése érdekében:
public class GrpcServer {public static void main (String [] args) {Server server = ServerBuilder .forPort (8080) .addService (new HelloServiceImpl ()). build (); server.start (); server.awaitTermination (); }}
Itt ismét az építőt használjuk egy gRPC szerver létrehozására a 8080-as porton, és hozzáadjuk a HelloServiceImpl általunk meghatározott szolgáltatást. Rajt() elindítaná a szervert. Példánkban felhívni fogjuk awaitTermination () hogy a kiszolgáló az előtérben fusson és blokkolja a felszólítást.
7. Az Ügyfél létrehozása
A gRPC olyan csatornakonstrukciót nyújt, amely kivonja az alapul szolgáló részleteket mint a csatlakozás, a csatlakozás összevonása, a terhelés kiegyenlítése stb.
A segítségével létrehozunk egy csatornát ManagedChannelBuilder. Itt adjuk meg a szerver címét és portját.
Sima szöveget fogunk használni titkosítás nélkül:
public class GrpcClient {public static void main (String [] args) {ManagedChannel channel = ManagedChannelBuilder.forAddress ("localhost", 8080) .usePlaintext () .build (); HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub (csatorna); HelloResponse helloResponse = stub.hello (HelloRequest.newBuilder () .setFirstName ("Baeldung") .setLastName ("gRPC") .build ()); csatorna.leállítás (); }}
Ezután létre kell hoznunk egy csonkot, amelyet felhasználunk a tényleges távoli híváshoz Helló(). A csonk az elsődleges módja annak, hogy az ügyfelek kölcsönhatásba lépjenek a szerverrel. Automatikusan létrehozott csonkok használatakor a csonk osztálynak lesz konstruktora a csatorna beburkolására.
Itt blokkoló / szinkron csonkot használunk, így az RPC hívás megvárja a kiszolgáló válaszát, és vagy választ ad, vagy kivételt hoz. A gRPC további két típusú csonkot tartalmaz, amelyek megkönnyítik a nem blokkoló / aszinkron hívásokat.
Végül itt az ideje a Helló() RPC hívás. Itt adjuk át a HelloRequest. Használhatjuk az automatikusan létrehozott beállítókat a keresztnév, vezetéknév tulajdonságai a HelloRequest tárgy.
Visszaérjük a HelloResponse a szerverről visszaküldött objektum.
8. Következtetés
Ebben az oktatóanyagban azt láttuk, hogyan használhatnánk a gRPC-t a két szolgáltatás közötti kommunikáció fejlesztésének megkönnyítésére azáltal, hogy a szolgáltatás meghatározására összpontosítunk, és hagyjuk, hogy a gRPC kezelje az összes kazánlap kódját.
Szokás szerint a forrásokat a GitHubon találja meg.