Har du mikrotjenester? Da bør du sjekke ut gRPC!

Teknologien stammer fra 60-tallet, men Googles løsning bør brukes mer i 2021, mener Mads.

Mads Lundegaard slår et slag for teknologien gRPC. 📸: Privat
Mads Lundegaard slår et slag for teknologien gRPC. 📸: Privat Vis mer

For noen uker siden leste jeg intervjuet med Camilla Marie Dalan som ga en kort introduksjon på GraphQL, noe som vekket en tanke i meg: Hvorfor har ingen skrevet om gRPC?

Jeg begynte å tenke litt, men landet til slutt på at årsaken trolig er fordi andelen som bruker gRPC er relativ lav i forhold til GraphQL.

Jeg satt meg derfor et litt hårete målet om å gjøre noe med dette, derfor har jeg skrevet en liten intro til gRPC.

Hva er gRPC?

gRPC er et rammeverk som har blitt utviklet av Google og står derfor for Google Remote Procedure Call.

RPC er ikke en ny oppfinnelse, tvert imot, det stammer tilbake fra sent 1960-tallet. gRPC startet derimot hos Google, under navnet "stubby" og ble brukt for å sammenkoble interne mikrotjenester på tvers av plattformer og datasentre.

I 2015 bestemte Google seg for å lage en ny versjon av "stubby" og samtidig gjøre det til åpen kildekode. Siden den gang har gRPC vært under konstant utvikling og har blitt tatt i bruk av flere og flere firmaer, av blant annet Netflix og Cisco for å nevne noen.

Hvorfor skal jeg bry meg?

Om dette er noe du burde ta i bruk kommer helt an på hva du har behov for.

gRPC er ikke nødvendigvis en teknologi alle må bruke, da det optimale bruksområdet er noe spesifikk, nemlig mikrotjenester. Mikrotjenester er ikke noe alle anvender og er heller ikke noe jeg vil oppfordre alle til å benytte, med mindre du har behov for det.

Det er først når du har en samling med interne tjenester, som alle skal kunne snakke sammen, at gRPC virkelig får vist hva det er verdt. Hvis du fortsatt sliter litt med å se nytten av gRPC, så ta det med ro; jeg skal komme med noen eksempler.

Hvordan funker gRPC?

gRPC benytter seg av protocol buffers som Interface Definition Language, noe som vil si at all kommunikasjon som kan foregå blir på forhånd definert i såkalte proto-filer.

Hvis du for eksempel vil definere en ansatt, så kan det gjøres som følgende:

message Employee {
   int32 id = 1;
   string name = 2;
   repeated string teams = 3;
}

Som du kanskje la merke til, så er hvert felt nummerert. Grunnen til dette er fordi proto-filer sendes binært for å optimalisere kommunikasjonen mest mulig. Numrene benyttes derfor for å identifisere hvert felt når det er i binært format.

Videre kan det være verdt å presisere at repeated kan ses på som en liste, som i dette tilfellet ville vært en liste med strenger. Når disse filene kompileres vil det bli autogenerert nyttige funksjoner som get-ere, set-ere og iteratorer, noe som er ganske digg å slippe å skrive manuelt.

Definisjon av tjenester blir også definert i proto-filer, på samme måte som nyttelasten:

service EmployeeSearchService {
   rpc Search(EmployeeSearchRequest) returns (EmployeeSearchResponse);
}

Her har vi definert en tjeneste for søk på ansatte i et firma. Når man skal søke på en ansatt sender man inn en request som kan inneholde søkekriterier, også får man tilbake en response med ansatte som oppfyller kravet.

Ganske enkelt, ikke sant?

En av fordelene med gRPC er at man på forhånd har definert alt kommunikasjon som kan skje. Det betyr at hvis du en dag skal ha behov for å benytte deg av en ny mikrotjeneste, så ligger alle tjenester til mikrotjenesten allerede definert. Hvis man da har et sentral distribuert repository med gRPC-filene, så kan man i teorien benytte seg av hvilken som helst tjeneste når man har behov for den.

Fordi gRPC ikke er avhengig av hvilket språk du bruker så betyr det også at alle tjenestene kan være utviklet i hvilket som helst språk uten at det har noe å si for kommunikasjonen. Det er ikke så verst.

Illustrasjonen viser hvordan kommunikasjon kan skje på tvers av plattformer. 📸: grpc.io
Illustrasjonen viser hvordan kommunikasjon kan skje på tvers av plattformer. 📸: grpc.io Vis mer

Men hvorfor kan jeg ikke bruke REST + JSON?

Det er lov å bruke REST + JSON til kommunikasjon selv om det kanskje ikke er det raskeste der ute. En fordel med gRPC derimot, er jo nemlig at det går fort, og da snakker vi fort fort.

Et par grunner til dette er fordi gRPC benytter seg av protobuf-filer som kompileres til binært, noe som reduserer mengden data som må sendes. Samtidig er jo alt av kommunikasjon forhåndsdefinert i proto-filene, noe som gjør at du sparer mye tid på deserialisering av dataen.

Det betyr derimot ikke at du må manuelt skrive inn data binært når du skal teste ut endepunkter. gRPC har nemlig støtte for JSON og mange andre formater.

En annen faktor er at gRPC i vesentlig større grad benytter seg av funksjonaliteten HTTP 2.0 tilbyr. Mye REST trafikk kjører på HTTP 2.0, men tar ikke i bruk det fulle potensialet av funksjonaliteten som HTTP 2.0 tilbyr. Et eksempel på dette er at HTTP 2.0 tilbyr klient, server og toveis -streaming, noe gRPC har full støtte for.

Hvor mye raskere er det egentlig?

Jo, det skal jeg fortelle, du er nemlig ikke den første som har lurt på dette.

I 2019 kjørte Ruwan Fernando en undersøkelse hvor han sammenlignet REST mot gRPC ved kommunikasjon av ulik nyttelast.

Det er store forskjeller ute og går. Det som kanskje er mest bemerkelsesverdig er forskjellen på post av stor nyttelast ved 100 iterasjoner (uten å bruke streaming).

REST bruker 1529,5 ms på operasjonen, mens gRPC bruker 145,2 ms på samme operasjon. Her er det altså snakk om opp til 10x forbedring i ytelse. Det er også verdt å merke seg at henting av stor nyttelast ved 100 iterasjoner (uten å bruke streaming) er rundt 7,5 ganger raskere ved gRPC.

For å konkludere så kan det være mye ytelse og besparelser å hente bare ved å benytte seg av gRPC.

Okey, gRPC er faktisk ikke så verst, men det virker litt for godt til å være sant?

Okey, nå over til den litt kjipere delen, nemlig ulempene. gRPC er ikke bare en dans på roser, det har sine ulemper også.

Den første og kanskje kjipeste ulempen er at det ikke er like mye støtte opp mot gRPC sammenlignet med REST. Det jeg egentlig hinter til er at det finnes flere nyttige verktøy utviklet til REST sammenlignet med gRPC.

Det største problemet etter min mening er at det ikke finnes noe skikkelig bra verktøy for å teste tjenester på gRPC. På REST har man for eksempel Postman som byr på et helt spekter av ulike nyttige funksjoner du kan benytte deg av for å teste endepunktene din på en REST-tjeneste. I gRPC må du derimot ta i bruk verktøy basert på open source prosjekter som kanskje ikke får like mye kjærlighet som de burde hatt.

«En annen ulempe er at det kan ta lengre tid å implementere funksjonalitet med gRPC.»

Et eksempel på dette er Bloomrpc som plutselig sluttet å funke fordi et Let's Encrypt-sertifikat utgikk. Det har enda ikke blitt fikset og man må derfor begynne å bruke et nytt verktøy.

En annen ulempe er at det kan ta lengre tid å implementere funksjonalitet med gRPC, noe som Ruwan Fernando påpeker i artikkelen sin. Mye av dette skyldes at det finnes mindre støtte for gRPC i ulike rammeverk sammenlignet med REST som er desidert mest utbredt. Det er derimot verdt å nevne at den artikkelen ble skrevet i 2019 og mye har skjedd siden den tid.

Okey, nå vet jeg hva gRPC går ut på - hva gjør jeg nå?

En god start på å lære mer om gRPC er å lese på dokumentasjonen på nettsiden deres. Det finnes også mange gode artikler skrevet av tredjeparter som tar for seg bruk av gRPC.

I tillegg vil jeg også oppfordre til å lese om funksjonaliteten som finnes i protocol buffers. Her har Google mye bra lesestoff hvor de går grunnleggende gjennom funksjonalitet og eventuelle problemstillinger som kan oppstå.

Selv om jeg har presentert hvor fantastisk gRPC er så betyr det ikke at du skal gå hjem og skrote all koden som bruker REST. Som jeg tidligere nevnte så må du se hvilke behov du har og hva du skal oppnå. Hvis du benytter deg av monolithic arkitektur så er nok ikke gRPC det beste å bruke.

Skal du derimot utvikle mikrotjenester, så kan gRPC være noe som sterkt bør vurderes.