Rad s Apache Thrift

1. Pregled

U ovom ćemo članku otkriti kako razviti klijentsko-poslužiteljske programe na više platformi uz pomoć RPC okvira nazvanog Apache Thrift.

Pokrivat ćemo:

  • Definiranje vrsta podataka i sučelja usluga s IDL-om
  • Instaliranje knjižnice i generiranje izvora za različite jezike
  • Implementacija definiranih sučelja u određenom jeziku
  • Implementacija softvera klijent / poslužitelj

Ako želite prijeći izravno na primjere, prijeđite ravno na odjeljak 5.

2. Apaška štedljivost

Apache Thrift izvorno je razvio Facebook razvojni tim, a trenutno ga održava Apache.

U usporedbi s međuspremnicima protokola, koji upravljaju procesima serializacije / deserializacije objekata na više platformi, Štedljivost se uglavnom fokusira na sloj komunikacije između komponenata vašeg sustava.

Thrift koristi poseban jezik opisa sučelja (IDL) za definiranje vrsta podataka i uslužnih sučelja koja se pohranjuju kao .štedljivost datoteke i kasnije korištene kao unos od strane sastavljača za generiranje izvornog koda klijentskog i poslužiteljskog softvera koji komuniciraju putem različitih programskih jezika.

Da biste u svom projektu koristili Apache Thrift, dodajte ovu ovisnost o Mavenu:

 org.apache.thrift libthrift 0.10.0 

Najnoviju verziju možete pronaći u spremištu Maven.

3. Jezik opisa sučelja

Kao što je već opisano, IDL omogućuje definiranje komunikacijskih sučelja na neutralnom jeziku. Ispod ćete pronaći trenutno podržane vrste.

3.1. Vrste baze

  • bool - logička vrijednost (true ili false)
  • bajt - 8-bitni potpisan cijeli broj
  • i16 - 16-bitni cijeli broj s potpisom
  • i32 - 32-bitni cijeli broj s potpisom
  • i64 - 64-bitni cijeli broj s potpisom
  • dvostruko - 64-bitni broj s pomičnom zarezom
  • niz - tekstualni niz kodiran UTF-8 kodiranjem

3.2. Posebne vrste

  • binarni - slijed nekodiranih bajtova
  • neobavezna - Java 8 Neobvezno tip

3.3. Strukture

Štedljivost građevine su ekvivalent klase u OOP jezicima, ali bez nasljeđivanja. A strukt ima skup jako otkucanih polja, svako s jedinstvenim imenom kao identifikatorom. Polja mogu imati razne bilješke (numerički ID-ovi polja, neobavezne zadane vrijednosti itd.).

3.4. Spremnici

Štedljivi kontejneri su snažno tipizirani kontejneri:

  • popis - poredani popis elemenata
  • postavljen - neuređeni skup jedinstvenih elemenata
  • karta - karta strogo jedinstvenih ključeva vrijednosti

Elementi spremnika mogu biti bilo koje valjane vrste štedljivosti.

3.5. Iznimke

Iznimke su funkcionalno jednake građevine, osim što nasljeđuju iz izvornih izuzetaka.

3.6. Usluge

Usluge su zapravo komunikacijska sučelja definirana pomoću Thrift tipova. Sastoje se od skupa imenovanih funkcija, svaka s popisom parametara i povratnim tipom.

4. Generiranje izvornog koda

4.1. Jezična podrška

Dug je popis trenutno podržanih jezika:

  • C ++
  • C #
  • Ići
  • Haskell
  • Java
  • Javascript
  • Node.js
  • Perl
  • PHP
  • Piton
  • Rubin

Cjelovit popis možete provjeriti ovdje.

4.2. Korištenje izvršne datoteke knjižnice

Samo preuzmite najnoviju verziju, izradite je i instalirajte ako je potrebno, i koristite sljedeću sintaksu:

cd put / do / štedljivost štedljivost -r --gen [JEZIK] [FILENAME]

U gore postavljenim naredbama, [JEZIK] je jedan od podržanih jezika i [NAZIV DATOTEKE] je datoteka s IDL definicijom.

Napomena -r zastava. Govori Thriftu da rekurzivno generira kod nakon što primijeti da je uključen u dano .štedljivost datoteka.

4.3. Korištenje dodatka Maven

Dodajte dodatak u svoj pom.xml datoteka:

 org.apache.thrift.tools maven-thrift-plugin 0.1.11 put / to / thrift thrift-sources generiranje-izvori kompajliranje 

Nakon toga samo izvršite sljedeću naredbu:

mvn čista instalacija

Imajte na umu da ovaj dodatak više neće imati daljnje održavanje. Molimo posjetite ovu stranicu za više informacija.

5. Primjer aplikacije klijent-poslužitelj

5.1. Definiranje štedljive datoteke

Napišimo nekoliko jednostavnih usluga s iznimkama i strukturama:

namespace cpp com.baeldung.thrift.impl prostor imena java com.baeldung.thrift.impl iznimka InvalidOperationException {1: i32 kôd, 2: opis niza} struct CrossPlatformResource {1: i32 id, 2: naziv niza, 3: neobavezni pozdrav niza} usluga CrossPlatformService {CrossPlatformResource get (1: i32 id) bacanja (1: InvalidOperationException e), void save (1: CrossPlatformResource resource) bacanja (1: InvalidOperationException e), list getList () bacanja (1: InvalidOperationExol p (p) ) baca (1: InvalidOperationException e)}

Kao što vidite, sintaksa je prilično jednostavna i samorazumljiva. Definiramo skup prostora imena (po jeziku implementacije), vrstu iznimke, strukturu i na kraju sučelje usluge koje će se dijeliti između različitih komponenata.

Zatim ga samo spremite kao usluga.štedljivost datoteka.

5.2. Sastavljanje i generiranje koda

Sada je vrijeme da pokrenemo kompajler koji će generirati kod za nas:

štedljivost -r -out generirano --gen java /path/to/service.thrift

Kao što vidite, dodali smo posebnu zastavu -aut da odredite izlazni direktorij za generirane datoteke. Ako niste dobili nikakve pogreške, generirano direktorij će sadržavati 3 datoteke:

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

Izradimo C ++ verziju usluge pokretanjem:

štedljivost -r -out generirano --gen cpp /path/to/service.thrift

Sada dobivamo 2 različite valjane implementacije (Java i C ++) istog sučelja usluge.

5.3. Dodavanje implementacije usluge

Iako je Thrift odradio veći dio posla za nas, još uvijek trebamo napisati vlastite implementacije CrossPlatformService. Da bismo to učinili, samo trebamo primijeniti a CrossPlatformService.Iface sučelje:

javna klasa CrossPlatformServiceImpl implementira CrossPlatformService.Iface {@Override public CrossPlatformResource get (int id) bacanja InvalidOperationException, TException {return new CrossPlatformResource (); } @Override public void save (CrossPlatformResource resource) baca InvalidOperationException, TException {saveResource (); } @Override javni popis getList () baca InvalidOperationException, TException {return Collections.emptyList (); } @Override public boolean ping () baca InvalidOperationException, TException {return true; }}

5.4. Pisanje poslužitelja

Kao što smo rekli, želimo izgraditi višeplatformsku aplikaciju klijent-poslužitelj, pa nam za to treba poslužitelj. Sjajna stvar kod Apache Thrift je što ima vlastiti komunikacijski okvir klijent-poslužitelj što komunikaciju čini komadom torte:

javna klasa CrossPlatformServiceServer {public void start () baca TTransportException {TServerTransport serverTransport = new TServerSocket (9090); poslužitelj = novi TSimpleServer (novi TServer.Args (serverTransport) .processor (novi CrossPlatformService.Processor (novi CrossPlatformServiceImpl ()))); System.out.print ("Pokretanje poslužitelja ..."); server.serve (); System.out.println ("gotovo."); } javna void stop () {if (server! = null && server.isServing ()) {System.out.print ("Zaustavljanje poslužitelja ..."); server.stop (); System.out.println ("gotovo."); }}} 

Prva stvar je definirati transportni sloj s provedbom TServerTransport sučelje (tačnije apstraktna klasa). Budući da govorimo o poslužitelju, moramo osigurati priključak za preslušavanje. Tada moramo definirati a TServer instance i odaberite jednu od dostupnih implementacija:

  • TSimpleServer - za jednostavan poslužitelj
  • TThreadPoolServer - za poslužitelje s više niti
  • TNonblockingServer - za neblokirajući višenitni poslužitelj

I na kraju, osigurajte implementaciju procesora za odabrani poslužitelj koji je za nas već generirao Thrift, tj. CrossPlatofformService.Processor razred.

5.5. Pisanje klijenta

I ovdje je klijentova implementacija:

TTransport transport = novi TSocket ("localhost", 9090); transport.open (); TProtocol protokol = novi TBinaryProtocol (transport); CrossPlatformService.Client client = novi CrossPlatformService.Client (protokol); logički rezultat = client.ping (); transport.close ();

Iz perspektive klijenta, akcije su prilično slične.

Prije svega definirajte transport i usmjerite ga na instancu našeg poslužitelja, a zatim odaberite prikladni protokol. Jedina razlika je u tome što ovdje inicijaliziramo instancu klijenta koju je, još jednom, već generirao Thrift, tj. CrossPlatformService.Client razred.

Budući da se temelji na .štedljivost definicije datoteka možemo izravno nazvati tamo opisane metode. U ovom konkretnom primjeru, client.ping () uputit će daljinski poziv poslužitelju koji će odgovoriti s pravi.

6. Zaključak

U ovom smo članku prikazali osnovne pojmove i korake u radu s Apache Thrift i pokazali smo kako stvoriti radni primjer koji koristi Thrift knjižnicu.

Kao i obično, svi se primjeri uvijek mogu pronaći u spremištu GitHub.