Die Netz­werk­tech­nik schreitet nach wie vor rasant voran. Um den stei­gen­den An­for­de­run­gen in ver­teil­ten Com­pu­ter­sys­te­men gerecht zu werden, wurde für Remote Procedure Calls ein neues System namens gRPC ent­wi­ckelt. Das „g“ steht dabei für Google, die maß­geb­lich an der Ent­wick­lung beteiligt waren. Wir erklären, was gRPC ist, wie es funk­tio­niert und wo es verwendet wird.

Was ist gRPC?

gRPC ist ein modernes Remote-Procedure-Call-System, das mit neu­ar­ti­gen Ver­fah­rens­tech­ni­ken die Kom­mu­ni­ka­ti­on in ver­teil­ten Client-Server-Ar­chi­tek­tu­ren besonders effizient abwickelt. Dabei setzt es – wie der Vorläufer RPC – auf Pro­zess­ebe­ne an. Cha­rak­te­ris­tisch für die In­ter­pro­zess­kom­mu­ni­ka­ti­on über gRPC ist das Trans­pa­renz­prin­zip: Die Zu­sam­men­ar­beit (teils weit) ent­fern­ter Instanzen ist so eng und rei­bungs­los, dass kein Un­ter­schied zu einer lokalen Kom­mu­ni­ka­ti­on zwischen ma­schi­nen­in­ter­nen Prozessen spürbar wird.

gRPC wurde 2015 zunächst von Google ent­wi­ckelt. Heute ist die Cloud Native Computing Foun­da­ti­on (siehe auch: Was ist Cloud Native?) fe­der­füh­rend bei der Ver­brei­tung und Wei­ter­ent­wick­lung der Kom­mu­ni­ka­ti­ons­tech­nik. gRPC ist Open Source, d. h. der Quelltext ist öf­fent­lich zu­gäng­lich, Än­de­run­gen und Wei­ter­ent­wick­lun­gen des Codes durch Dritte sind erwünscht und erlaubt.

Den Transport von Da­ten­strö­men zwischen ent­fern­ten Computern wickelt gRPC stan­dard­mä­ßig mit HTTP/2 ab, für die Struk­tu­rie­rung und Ver­ar­bei­tung der Daten sind die von Google ent­wi­ckel­ten Protocol Buffers zuständig. Letztere werden in Form von einfachen Text­da­tei­en mit der Endung .proto ge­spei­chert.

gRPC wird häufig als Framework be­zeich­net. Zu den Be­son­der­hei­ten eines Frame­works zählt, dass es Ent­wick­lern einen Pro­gram­mier­rah­men be­reit­stellt und dadurch Zeit und Arbeit spart. So enthält das stan­dar­di­sier­te Gerüst von gRPC bereits ver­schie­de­ne Funk­tio­nen und Elemente, die nicht immer wieder neu pro­gram­miert werden müssen. Das gRPC-Framework definiert zudem genormte Schnitt­stel­len zu be­stimm­ten Quellen (z. B. Da­ten­ban­ken).

So funk­tio­niert gRPC: Viel­spra­chig und effizient durch Protocol Buffers und HTTP/2

Protocol Buffers (Protobuf) erfüllen im gRPC-System mehrere Funk­tio­nen: Sie dienen als Interface De­fi­ni­ti­on Language (Schnitt­stel­len­be­schrei­bungs­spra­che, kurz: IDL) und be­schrei­ben eine Schnitt­stel­le auf sprach­un­ab­hän­gi­ge Weise. Sie sind also nicht an eine spezielle Pro­gram­mier­spra­che (z. B. Java oder C) gebunden. Außerdem de­fi­nie­ren sie die zu ver­wen­den­den Services und be­reit­ge­stell­te Funk­tio­nen. Für jede Funktion kann angegeben werden, welche Parameter mit einer Anfrage geschickt werden und was als Rück­ga­be­wert erwartet werden kann.

Aus der Remote-Per­spek­ti­ve dienen Protocol Buffers als das zu­grun­de­lie­gen­de Nach­rich­ten­aus­tausch­for­mat, das die Nach­rich­ten­struk­tu­ren, -typen und -objekte bestimmt. Sie sorgen dafür, dass Client und Server sich „verstehen“ und auch über große Ent­fer­nun­gen hinweg als funk­tio­na­le und möglichst ef­fi­zi­en­te Einheit operieren.

Der Ablauf eines gRPC-Calls sieht bei einer Da­ten­bank­ab­fra­ge (z. B. „Suche nach Ar­ti­kel­vor­rat im Lager“) fol­gen­der­ma­ßen aus:

  • Bevor die Suche überhaupt ab­ge­wi­ckelt werden kann, braucht es Vor­be­rei­tun­gen. Ser­ver­sei­tig werden auf Basis der Protocol Buffers zunächst ein Service sowie ein gRPC-Server im­ple­men­tiert. Der an­fra­gen­de Client generiert sei­ner­seits einen dazu passenden Stub. Steht dieser zur Verfügung, ruft die Client-Anwendung die ent­spre­chen­de Funktion („Such­an­fra­ge nach Ar­ti­kel­be­stand“) im Stub auf.
  • An­schlie­ßend wird die Anfrage über das Netzwerk an den Server geschickt. Nach deren Empfang mithilfe einer ge­eig­ne­ten Service-Schnitt­stel­le startet der gRPC-Server die ei­gent­li­che Pro­dukt­su­che in der Datenbank.
  • Danach sendet der Server die Antwort an den Client Stub, der den Rück­ga­be­wert an die ur­sprüng­li­che An­fra­ge­instanz wei­ter­lei­tet (z. B. „Zahl der ge­fun­de­nen Artikel“).

Client- und ser­ver­sei­ti­ge An­wen­dun­gen können in un­ter­schied­li­chen Pro­gram­mier­spra­chen ge­schrie­ben werden. gRPC über­win­det diese Grenzen durch spezielle Schnitt­stel­len und Über­set­zungs­me­cha­nis­men.

Für den in­ter­ma­schi­nel­len Hin- und Rück­trans­port der Da­ten­strö­me (Proto Request und Proto Response) wird HTTP/2 in spezielle Netz­werk­pro­to­kol­le wie TCP/IP oder UDP/IP ein­ge­bet­tet. Die Streams trans­fe­rie­ren kompakte Bi­när­da­ten, die bei der für Remote Procedure Calls typischen Se­ria­li­sie­rung (Mar­shalling) entstehen. Um die voll­kom­men abs­trak­ten Da­ten­struk­tu­ren client- und ser­ver­sei­tig in weiteren Schritten ver­ar­bei­ten zu können, wird das Über­mit­tel­te auch wieder de­se­ria­li­siert (Un­mar­shalling).

gRPC-Workflow und erste Schritte via Protocol Buffers

Der typische gRPC-Workflow gliedert sich in vier Schritte:

  1. De­fi­ni­ti­on des Ser­vice­ver­trags für die In­ter­pro­zess­kom­mu­ni­ka­ti­on: Die auf­zu­set­zen­den Services sowie grund­le­gen­de Parameter und Rück­ga­be­ty­pen, die per Remote auf­ge­ru­fen werden können, werden bestimmt.
  2. Erzeugung des gRPC-Codes aus der .proto-Datei: Spezielle Compiler (Kom­man­do­zei­len­werk­zeu­ge mit dem Namen „protoc“) ge­ne­rie­ren aus ge­spei­cher­ten .proto-Dateien den ope­ra­ti­ven Code mit den ent­spre­chen­den Klassen für eine ge­wünsch­te Ziel­spra­che (z. B. C++, Java).
  3. Im­ple­men­tie­rung des Servers in der gewählten Sprache.
  4. Er­stel­lung des Client Stubs, der den Service aufruft; an­schlie­ßend wird bzw. werden die Anfrage(n) über Server und Client(s) ab­ge­wi­ckelt.

Bei einer Da­ten­bank­ab­fra­ge, die nach einem Produkt in einem La­ger­be­stand (inventory) sucht, sehen die ersten konkreten Schritte in der aktuellen Protocol-Buffers-Syntax (Version: proto3) wie folgt aus:

syntax = "proto3";
package grpc_service;
import "google/protobuf/wrappers.proto";
service InventoryService {
	rpc getItemByName(google.protobuf.StringValue) returns (Items);
	rpc getItemByID(google.protobuf.StringValue) returns (Item);
	 rpc addItem(Item) returns (google.protobuf.BoolValue);
}
 
message Items {
  string itemDesc = 1;
  repeated Item items = 2;
}
 
message Item {
	string id = 1;
	string name = 2;
	string description = 3;
}

In dem Beispiel verwendet die Da­ten­bank­ab­fra­ge spezielle „Wrapper-Bi­blio­the­ken“ des gRPC-Frame­works, die relevante Über­set­zungs­pro­ze­du­ren bereits vor­pro­gram­miert zur Verfügung stellen und zu Beginn im­por­tiert werden. Sie sorgen in viel­spra­chi­gen und dis­pa­ra­ten Client-Server-Ar­chi­tek­tu­ren dafür, dass ei­gent­lich in­kom­pa­ti­ble Schnitt­stel­len mit­ein­an­der kom­mu­ni­zie­ren können. So werden etwa die zum Lesen und Schreiben von Nach­rich­ten er­for­der­li­chen Klassen generiert.

Wie die Ser­vice­de­fi­ni­ti­on (inventory.proto) die Abfrage einer Datenbank in einer Client-Server-Ar­chi­tek­tur regelt, zeigt folgendes Schaubild:

HTTP/2: Leis­tungs­op­ti­mier­tes Streaming

HTTP/2 spielt bei gRPC eine zentrale Rolle, da es den Transfer kompakter Bi­när­da­ten er­mög­licht und den Austausch von Nach­rich­ten und Daten besonders effizient gestaltet. Das Netz­werk­pro­to­koll stellt vier Varianten für Remote Procedure Calls zur Verfügung:

  1. Unäre RPCs sind das ein­fachs­te gRPC-Muster. Dabei sendet der Client eine einzelne An­for­de­rung an den Server. Wie bei einem normalen Funk­ti­ons­auf­ruf erhält er dann eine einzelne Antwort zurück.

Beispiel: rpc SayHello (Hell­o­Re­quest) gibt zurück (Hell­o­Re­spon­se)

  1. Bei Server-Streaming-RPCs ist ein kom­ple­xe­rer Nach­rich­ten­aus­tausch innerhalb eines einzelnen RPC-Aufrufs möglich. Zunächst sendet der Client eine An­for­de­rung an den Server. Dann erhält er als Rück­ant­wort vom Server einen Stream mit einer um­fang­rei­che­ren Nach­rich­ten­fol­ge (ef­fi­zi­en­te Nach­rich­ten­be­stel­lung innerhalb eines einzelnen RPC-Aufrufs). Der Client liest diesen Stream dann aus, bis keine Nach­rich­ten mehr vorhanden sind.

Beispiel: rpc Lot­sOf­Re­pli­es (Hell­o­Re­quest) gibt zurück (stream Hell­o­Re­spon­se)

  1. Client-Streaming-RPC kehrt den Prozess um: Der Client schreibt eine Folge von Nach­rich­ten und sendet diese dann via Stream an den Server. Nachdem der Client die Nach­rich­ten verfasst hat, wartet er darauf, dass der Server sie liest und die Antwort zu­rück­gibt. Auch hier erfolgt die Nach­rich­ten­be­stel­lung innerhalb eines einzelnen RPC-Aufrufs.

Beispiel: rpc Lot­sOf­Gree­tings (stream Hell­o­Re­quest) gibt zurück (Hell­o­Re­spon­se)

  1. Bi­di­rek­tio­na­le Streaming-RPCs sind die kom­ple­xes­te Kom­mu­ni­ka­ti­ons­form, bei der beide Seiten eine Folge von Nach­rich­ten senden. Beide Daten-Streams arbeiten un­ab­hän­gig von­ein­an­der, so dass Client und Server in be­lie­bi­ger Rei­hen­fol­ge lesen und schreiben können: So kann der Server warten, bis alle Client-Nach­rich­ten ein­ge­gan­gen sind, bevor er seine Antworten schreibt. Er kann aber auch ab­wech­selnd eine Nachricht lesen und dann eine Nachricht schreiben. Möglich ist zudem eine andere Kom­bi­na­ti­on von Lese- und Schreib­vor­gän­gen.

Beispiel: rpc BidiHello (stream Hell­o­Re­quest) gibt zurück (stream Hell­o­Re­spon­se)

Die Varianten 2 bis 4 eta­blie­ren mit ver­schach­tel­ten Requests ein besonders ef­fi­zi­en­tes Mul­ti­plex­ing, bei dem innerhalb einer einzelnen TCP-Ver­bin­dung mehrere Signale gebündelt und simultan über das Netzwerk über­tra­gen werden können. Blo­ckie­run­gen im Da­ten­ver­kehr werden durch das leis­tungs­fä­hi­ge HTTP/2-Protokoll über­wun­den.

Die Vor- und Nachteile von gRPC

gRPC hat viele Vorteile: Die Tech­no­lo­gie lässt sich relativ leicht umsetzen, weil sie bei der Er­stel­lung der .proto-Dateien eine einfache und recht schnell er­lern­ba­re IDL verwendet. Damit können selbst betagte Programme un­kom­pli­ziert um eine leis­tungs­fä­hi­ge gRPC-Schnitt­stel­le erweitert werden und deutlich schneller auch große Dateien über­tra­gen.

Zudem ist gRPC vielfach getestet und hoch­ska­lier­bar, wodurch auch kom­ple­xe­re und um­fang­rei­che­re Kom­mu­ni­ka­tio­nen z. B. in global ver­netz­ten Client-Server-Ar­chi­tek­tu­ren als Ein­satz­ge­biet infrage kommen. Dabei erhöht HTTP/2 die Effizienz nicht nur durch Mul­ti­plex­ing und bi­di­rek­tio­na­les Streaming. Es sind auch Header-Kom­pri­mie­run­gen möglich, die das Da­ten­vo­lu­men von An­for­de­run­gen und Antworten im Netzwerk nen­nens­wert re­du­zie­ren.

Durch den mehr­schich­ti­gen und stark stan­dar­di­sier­ten Aufbau des gRPC-Frame­works lässt sich der Pro­gram­mier­auf­wand re­du­zie­ren. Ent­wick­ler können sich somit primär auf die Im­ple­men­tie­rung der Methoden kon­zen­trie­ren. Sind An­pas­sun­gen nötig, pro­fi­tie­ren Pro­gram­mie­rer und Sys­tem­ent­wick­ler von der freien Zu­gäng­lich­keit der Quell­codes.

Protocol Buffers und die ent­spre­chen­den Protobuf Compiler er­mög­li­chen zudem eine grenz­über­schei­ten­de Kom­mu­ni­ka­ti­on: Un­ter­schied­li­che Be­triebs­sys­te­me, disparate Kom­po­nen­ten von Client-Server-Ar­chi­tek­tu­ren und ver­schie­de­ne Pro­gram­mier­spra­chen stellen keine Hürde mehr dar. So kann eine Software, die in C ge­schrie­ben ist, etwa mit Java-Software kom­mu­ni­zie­ren. Protobuf Compiler stehen mitt­ler­wei­le für viele weitere Sprachen zur Verfügung, z. B. für C#, C++, Go, Objective-C, Java, Python, Node.js, Android Java, Swift, Ruby und PHP.

Vor­teil­haft ist auch die Fle­xi­bi­li­tät von gRPC. Es kann bei­spiels­wei­se glei­cher­ma­ßen zum Da­ten­aus­tausch von Mi­cro­ser­vices oder von mobilen Apps verwendet werden, die ihre Daten mit Servern teilen. Ein weiterer Pluspunkt: Das Protokoll erlaubt die Im­ple­men­tie­rung von aktuellen Si­cher­heits­tech­no­lo­gien. gRPC verfügt über eine in­te­grier­te Au­then­ti­fi­zie­rung und fördert die Ver­wen­dung von SSL/TLS zur Au­then­ti­fi­zie­rung und zur Ver­schlüs­se­lung des Aus­tauschs.

Zu den Schwächen von gRPC zählen: Das Testen von gRPC-Schnitt­stel­len ist beim der­zei­ti­gen Stand der Ent­wick­lung noch ver­bes­se­rungs­wür­dig. gRPC-Nach­rich­ten, die mit protobuf codiert werden, sind nicht von Menschen lesbar. Bei der Analyse des Da­ten­ver­kehrs und speziell bei der Feh­ler­su­che und -behebung (Debuggen) müssen also zu­sätz­li­che Instanzen ein­ge­setzt werden, um den Code in eine ver­ständ­li­che Form zu über­füh­ren und dadurch Feh­ler­quel­len zu lo­ka­li­sie­ren. Weitere Nachteile re­sul­tie­ren aus der Ver­net­zung von ver­teil­ten Client-Server-Ar­chi­tek­tu­ren. gRPC verbindet Rechner über Ent­fer­nun­gen und ist somit an­fäl­li­ger als lokale Systeme. Es ist von einem stabilen und leis­tungs­fä­hi­gen Netz abhängig, zudem sollten Netzwerk, Da­ten­ver­kehr, Über­tra­gungs­pro­to­kol­le sowie Client und Server Hackern keine An­griffs­punk­te bieten. Ein weiterer Nachteil ist, dass gRPC kein Mul­ti­cas­ting un­ter­stützt.

gRPC und REST im Vergleich

Aufgrund der positiven Ei­gen­schaf­ten stellt gRPC eine kon­kur­renz­fä­hi­ge Al­ter­na­ti­ve zu REST (Re­pre­sen­ta­tio­nal State Transfer) dar. Letzteres eignet sich besonders gut für einfache Services, während gRPC seine Stärken bei kom­ple­xe­ren Schnitt­stel­len (APIs) und Services ausspielt. REST nutzt für den Da­ten­aus­tausch zwischen An­wen­dun­gen in der Regel das Da­ten­for­mat JSON, das text­ba­siert operiert und dadurch die Netz­werk­res­sour­cen belastet.

gRPC hingegen kann durch Protocol Buffers und HTTP/2 einen deutlich kom­pak­te­ren Da­ten­strom or­ga­ni­sie­ren. So wird der Spei­cher­be­darf durch Se­ria­li­sie­rung und Bi­na­ri­sie­rung der Daten im Vergleich etwa zu JSON um nahezu 70 Prozent gesenkt. Zudem sorgt das bi­di­rek­tio­na­le Streaming, das ohne Blo­ckie­run­gen beim Da­ten­aus­tausch funk­tio­niert, gegenüber REST für we­sent­li­che Leistungs- und Ge­schwin­dig­keits­vor­tei­le.

Derzeit ist die Zu­sam­men­ar­beit mit Web-Apps ver­bes­se­rungs­wür­dig, da diese häufig nicht für den Einsatz von Pro­to­koll­puf­fern, den gRPC-typischen „Vertrag-zuerst-Ansatz“ sowie die Contract First APIs des gRPC-Frame­works optimiert sind. Nach­tei­lig für die Zu­sam­men­ar­beit mit Web­ap­pli­ka­tio­nen ist, dass noch kein gRPC-Dienst direkt von einem Browser aus auf­ge­ru­fen werden kann. Bei REST ist das kein Problem, da das klas­si­sche HTTP-Protokoll im Gegensatz zum neueren HTTP/2 von allen Browsern un­ter­stützt wird. Al­ler­dings lässt sich das Manko mit ver­tret­ba­rem Aufwand umgehen, sodass derselbe Dienst für eine Web­ap­pli­ka­ti­on und eine mobile App ein­ge­setzt werden kann. Eine Option in diesem Bereich ist gRPC-Web. gRPC-Ent­wick­ler arbeiten noch an weiteren Lösungen, die die Zu­sam­men­ar­beit von gRPC und web­ba­sier­ten Tools möglichst einfach gestalten sollen.

Wo wird gRPC verwendet?

gRPC eignet sich besonders für eine ef­fi­zi­en­te In­ter­pro­zess­kom­mu­ni­ka­ti­on in ver­teil­ten Client-Server-Ar­chi­tek­tu­ren, die Wert auf niedrige Latenz und einen hohen Daten- und Nach­rich­ten­durch­satz legt. In und zwischen von­ein­an­der ent­fern­ten Re­chen­zen­tren wird gRPC häufig ein­ge­setzt, um Dienste oder Mi­cro­ser­vices mit­ein­an­der zu verbinden. Da gRPC-Tools die meisten gängigen Ent­wick­lungs­spra­chen un­ter­stüt­zen, werden sie häufig in mehr­spra­chi­gen Um­ge­bun­gen verwendet.

Schnel­lig­keit, Effizienz und Viel­spra­chig­keit be­güns­ti­gen den Einsatz von gRPC im mobilen Bereich und bei der Kom­mu­ni­ka­ti­on von Apps. gRPC regelt vermehrt die letzte Meile ver­teil­ter Da­ten­ver­ar­bei­tung, indem es Geräte, mobile An­wen­dun­gen und Browser mit Backend-Diensten verbindet.

Das leis­tungs­fä­hi­ge Streaming via HTTP/2 prä­de­sti­niert gRPC zudem für die Punkt-zu-Punkt-Echt­zeit­kom­mu­ni­ka­ti­on. Das Internet of Things (Smart-Home-Tech­no­lo­gien) pro­fi­tiert von dem res­sour­cen­scho­nen­den Verfahren, da es vermehrt die Kom­mu­ni­ka­ti­on von Low Resource Clients regelt. Aufgrund der Leis­tungs­vor­tei­le und der einfachen Ent­wick­lung könnte die Kom­mu­ni­ka­ti­ons­tech­nik in Zukunft in der Cloud eine führende Rolle spielen und damit die der­zei­ti­ge Dominanz von REST re­la­ti­vie­ren. gRPC wird momentan ebenfalls als Al­ter­na­ti­ve zu XML (Ex­ten­si­ble Markup Language) gehandelt.

Hinweis

XML ist ein häufig ver­wen­de­tes Format zum Da­ten­aus­tausch und zur struk­tu­rier­ten Spei­che­rung von In­for­ma­tio­nen.

Zum Hauptmenü