Jobber med Apache Thrift

1. Oversikt

I denne artikkelen vil vi oppdage hvordan vi kan utvikle plattformklient-server-applikasjoner ved hjelp av RPC-rammeverk kalt Apache Thrift.

Vi vil dekke:

  • Definere datatyper og tjenestegrensesnitt med IDL
  • Installere biblioteket og generere kildene til forskjellige språk
  • Implementering av de definerte grensesnittene på et bestemt språk
  • Implementering av klient- / serverprogramvare

Hvis du vil gå rett til eksempler, fortsett rett til seksjon 5.

2. Apache Thrift

Apache Thrift ble opprinnelig utviklet av Facebook-utviklingsteamet og vedlikeholdes for tiden av Apache.

Sammenlignet med protokollbuffere, som styrer prosesser for serieseriering / deserialisering på tvers av plattformer, Thrift fokuserer hovedsakelig på kommunikasjonslaget mellom komponenter i systemet ditt.

Thrift bruker et spesielt ID (Interface Interface Language) for å definere datatyper og tjenestegrensesnitt som er lagret som . sparsommelighet filer og brukes senere som input av kompilatoren for å generere kildekoden til klient- og serverprogramvare som kommuniserer over forskjellige programmeringsspråk.

For å bruke Apache Thrift i prosjektet ditt, legg til denne Maven-avhengigheten:

 org.apache.thrift libthrift 0.10.0 

Du finner den siste versjonen i Maven-arkivet.

3. Grensesnitt Beskrivelse Språk

Som allerede beskrevet tillater IDL å definere kommunikasjonsgrensesnitt på et nøytralt språk. Nedenfor finner du typene som støttes for øyeblikket.

3.1. Basetyper

  • bool - en boolsk verdi (sant eller usant)
  • byte - et 8-bits signert heltall
  • i16 - et 16-bits signert heltall
  • i32 - et 32-bits signert heltall
  • i64 - et 64-bits signert heltall
  • dobbelt - et 64-bit flytende nummer
  • streng - en tekststreng kodet ved bruk av UTF-8-koding

3.2. Spesielle typer

  • binær - en sekvens med ukodede byte
  • valgfri - en Java 8-er Valgfri type

3.3. Structs

Sparsommelighet structs tilsvarer klasser i OOP-språk, men uten arv. EN struct har et sett med sterkt typte felt, hver med et unikt navn som identifikator. Felter kan ha forskjellige merknader (numeriske felt-ID-er, valgfrie standardverdier osv.).

3.4. Beholdere

Sparske containere er sterkt typede containere:

  • liste - en ordnet liste over elementer
  • sett - et uordnet sett med unike elementer
  • kart - et kart med strengt unike nøkler til verdier

Beholderelementer kan være av en hvilken som helst gyldig Thrift-type.

3.5. Unntak

Unntak tilsvarer funksjonelt structs, bortsett fra at de arver fra de innfødte unntakene.

3.6. Tjenester

Tjenester er faktisk kommunikasjonsgrensesnitt som er definert ved hjelp av Thrift-typer. De består av et sett med navngitte funksjoner, hver med en liste over parametere og en returtype.

4. Generering av kildekode

4.1. Språkstøtte

Det er en lang liste med språk som støttes for øyeblikket:

  • C ++
  • C #
  • Haskell
  • Java
  • Javascript
  • Node.js
  • Perl
  • PHP
  • Python
  • Rubin

Du kan sjekke hele listen her.

4.2. Bruke bibliotekets kjørbare fil

Bare last ned den nyeste versjonen, bygg og installer den om nødvendig, og bruk følgende syntaks:

cd-bane / til / sparsommelighet -r --gen [SPRÅK] [FILENAME]

I kommandoene som er angitt ovenfor, [SPRÅK] er et av de støttede språkene og [FILNAVN] er en fil med IDL-definisjon.

Legg merke til -r flagg. Det forteller Thrift å generere kode rekursivt når den legger merke til at den inngår i en gitt . sparsommelighet fil.

4.3. Bruker Maven Plugin

Legg til pluginet i din pom.xml fil:

 org.apache.thrift.tools maven-thrift-plugin 0.1.11 path / to / thrift thrift-sources generere-kilder kompilere 

Etter det er det bare å utføre følgende kommando:

mvn ren installasjon

Merk at dette pluginet ikke lenger vil ha noe vedlikehold. Besøk denne siden for mer informasjon.

5. Eksempel på en klientserverapplikasjon

5.1. Definere Thrift File

La oss skrive noen enkle tjenester med unntak og strukturer:

namespace cpp com.baeldung.thrift.impl namespace java com.baeldung.thrift.impl unntak InvalidOperationException {1: i32-kode, 2: strengbeskrivelse} struct CrossPlatformResource {1: i32 id, 2: strengnavn, 3: valgfri strenghilsen} tjeneste CrossPlatformService {CrossPlatformResource get (1: i32 id) kaster (1: InvalidOperationException e), ugyldig lagring (1: CrossPlatformResource ressurs) kaster (1: InvalidOperationException e), liste getList () kaster (1: InvalidOperationException e), bool ) kaster (1: InvalidOperationException e)}

Som du kan se, er syntaksen ganske enkel og selvforklarende. Vi definerer et sett med navneområder (per implementeringsspråk), en unntakstype, en struktur og til slutt et tjenestegrensesnitt som vil bli delt på tvers av forskjellige komponenter.

Så er det bare å lagre det som en service. sparsommelighet fil.

5.2. Kompilering og generering av en kode

Nå er det på tide å kjøre en kompilator som vil generere koden for oss:

sparsommelighet -r -out generert --gen java /path/to/service.thrift

Som du kanskje ser, la vi til et spesielt flagg -ute for å spesifisere utdatakatalogen for genererte filer. Hvis du ikke fikk noen feil, kan generert katalogen inneholder 3 filer:

  • CrossPlatformResource.java
  • CrossPlatformService.java
  • InvalidOperationException.java

La oss generere en C ++ - versjon av tjenesten ved å kjøre:

sparsommelighet -r -out generert --gen cpp /path/to/service.thrift

Nå får vi 2 forskjellige gyldige implementeringer (Java og C ++) av samme tjenestegrensesnitt.

5.3. Legge til en tjenesteimplementering

Selv om Thrift har gjort det meste av arbeidet for oss, trenger vi fortsatt å skrive våre egne implementeringer av CrossPlatformService. For å gjøre det, trenger vi bare å implementere en CrossPlatformService.Iface grensesnitt:

offentlig klasse CrossPlatformServiceImpl implementerer CrossPlatformService.Iface {@Override public CrossPlatformResource get (int id) kaster InvalidOperationException, TException {return new CrossPlatformResource (); } @Override public void save (CrossPlatformResource resource) kaster InvalidOperationException, TException {saveResource (); } @Override public List getList () kaster InvalidOperationException, TException {return Collections.emptyList (); } @Override offentlig boolsk ping () kaster InvalidOperationException, TException {return true; }}

5.4. Skrive en server

Som vi sa, vi ønsker å bygge en plattform-klient-server-applikasjon, så vi trenger en server for det. Det som er bra med Apache Thrift, er at den har sitt eget klient-server-kommunikasjonsrammeverk som gjør kommunikasjon til et stykke kake:

offentlig klasse CrossPlatformServiceServer {offentlig ugyldig start () kaster TTransportException {TServerTransport serverTransport = ny TServerSocket (9090); server = ny TSimpleServer (ny TServer.Args (serverTransport). prosessor (ny CrossPlatformService.Processor (ny CrossPlatformServiceImpl ()))); System.out.print ("Starter serveren ..."); server.serve (); System.out.println ("gjort."); } public void stop () {if (server! = null && server.isServing ()) {System.out.print ("Stopping the server ..."); server.stop (); System.out.println ("gjort."); }}} 

Det første er å definere et transportlag med implementeringen av TServerTransport grensesnitt (eller abstrakt klasse, for å være mer presis). Siden vi snakker om server, må vi gi en port å lytte til. Da må vi definere en TServer forekomst og velg en av de tilgjengelige implementeringene:

  • TSimpleServer - for enkel server
  • TThreadPoolServer - for server med flere tråder
  • TNonblockingServer - for ikke-blokkerende server med flere tråder

Og til slutt, gi en prosessorimplementering for valgt server som allerede ble generert for oss av Thrift, dvs. CrossPlatofformService.Prosessor klasse.

5.5. Skrive en klient

Og her er klientens implementering:

TTransport = ny TSocket ("localhost", 9090); transport.open (); TProtocol protokoll = ny TBinaryProtocol (transport); CrossPlatformService.Client-klient = ny CrossPlatformService.Client (protokoll); boolsk resultat = client.ping (); transport.close ();

Fra et klientperspektiv er handlingene ganske like.

Først og fremst definerer du transporten og retter den mot serverforekomsten vår, og velg deretter passende protokoll. Den eneste forskjellen er at her initialiserer vi klientforekomsten som nok en gang allerede ble generert av Thrift, dvs. CrossPlatformService.Client klasse.

Siden det er basert på . sparsommelighet fildefinisjoner kan vi direkte kalle metoder beskrevet der. I dette spesielle eksemplet, client.ping () vil ringe til serveren som vil svare med ekte.

6. Konklusjon

I denne artikkelen har vi vist deg de grunnleggende konseptene og trinnene i arbeidet med Apache Thrift, og vi har vist hvordan du lager et arbeidseksempel som bruker Thrift-biblioteket.

Som vanligvis kan alle eksemplene alltid finnes i GitHub-depotet.


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