Introduksjon til Apache Curator

1. Introduksjon

Apache Curator er en Java-klient for Apache Zookeeper, den populære koordineringstjenesten for distribuerte applikasjoner.

I denne veiledningen introduserer vi noen av de mest relevante funksjonene som tilbys av Curator:

  • Connection Management - administrering av tilkoblinger og forsøk på nytt
  • Async - forbedring av eksisterende klient ved å legge til async-muligheter og bruk av Java 8 lambdas
  • Configuration Management - har en sentralisert konfigurasjon for systemet
  • Sterkt typede modeller - arbeider med typede modeller
  • Oppskrifter - gjennomføring av ledervalg, distribuerte låser eller skranker

2. Forutsetninger

Til å begynne med anbefales det å ta en rask titt på Apache Zookeeper og dens funksjoner.

For denne opplæringen antar vi at det allerede er en frittstående Zookeeper-forekomst som kjører på 127.0.0.1:2181; her er instruksjoner om hvordan du installerer og kjører den, hvis du bare har begynt.

Først må vi legge til kurator-x-async-avhengighet til vår pom.xml:

 org.apache.curator curator-x-async 4.0.1 org.apache.zookeeper zookeeper 

Den siste versjonen av Apache Curator 4.X.X har en hard avhengighet av Zookeeper 3.5.X som fortsatt er i beta akkurat nå.

I denne artikkelen skal vi i stedet bruke den siste stabile Zookeeper 3.4.11.

Så vi må ekskludere Zookeeper-avhengigheten og legge til avhengigheten for vår Zookeeper-versjon til vår pom.xml:

 org.apache.zookeeper dyrehage 3.4.11 

For mer informasjon om kompatibilitet, se denne lenken.

3. Tilkoblingsadministrasjon

Den grunnleggende brukssaken til Apache Curator er å koble til en kjørende Apache Zookeeper-forekomst.

Verktøyet gir en fabrikk for å bygge forbindelser til Zookeeper ved å bruke policyer for forsøk på nytt:

int sleepMsBetweenRetries = 100; int maxRetries = 3; RetryPolicy retryPolicy = nytt RetryNTimes (maxRetries, sleepMsBetweenRetries); CuratorFramework client = CuratorFrameworkFactory .newClient ("127.0.0.1:2181", retryPolicy); client.start (); assertThat (client.checkExists (). forPath ("/")). isNotNull ();

I dette raske eksemplet prøver vi tre ganger på nytt og venter 100 ms mellom prøvene igjen i tilfelle tilkoblingsproblemer.

Når du er koblet til Zookeeper ved hjelp av CuratorFramework klient, kan vi nå bla gjennom stier, få / angi data og egentlig samhandle med serveren.

4. Asynkronisering

Curator Async-modulen inneholder de ovennevnte CuratorFramework klienten for å tilby funksjoner som ikke blokkerer ved hjelp av CompletionStage Java 8 API.

La oss se hvordan forrige eksempel ser ut ved å bruke Async-innpakningen:

int sleepMsBetweenRetries = 100; int maxRetries = 3; RetryPolicy retryPolicy = nytt RetryNTimes (maxRetries, sleepMsBetweenRetries); CuratorFramework client = CuratorFrameworkFactory .newClient ("127.0.0.1:2181", retryPolicy); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (klient); AtomicBoolean eksisterer = ny AtomicBoolean (false); async.checkExists () .forPath ("/") .thenAcceptAsync (s -> exist.set (s! = null)); vente (). til (() -> hevder at (eksisterer. få ()). er sant ());

Nå, den checkExists () operasjonen fungerer i asynkron modus, og blokkerer ikke hovedtråden. Vi kan også kjede handlinger etter hverandre ved hjelp av thenAcceptAsync () metoden i stedet, som bruker CompletionStage API.

5. Konfigurasjonsadministrasjon

I et distribuert miljø er en av de vanligste utfordringene å administrere delt konfigurasjon blant mange applikasjoner. Vi kan bruke Zookeeper som et datalager hvor vi kan beholde konfigurasjonen.

La oss se et eksempel med Apache Curator for å hente og angi data:

CuratorFramework-klient = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (klient); Strengnøkkel = getKey (); Streng forventet = "min_verdi"; client.create (). forPath (nøkkel); async.setData () .forPath (nøkkel, forventet.getBytes ()); AtomicBoolean isEquals = ny AtomicBoolean (); async.getData () .forPath (nøkkel) .thenAccept (data -> isEquals.set (ny streng (data) .ekvivalenter (forventet))); venter (). til (() -> hevder at (isEquals.get ()). er sant ());

I dette eksemplet oppretter vi nodebanen, setter dataene i Zookeeper, og deretter gjenoppretter vi den og sjekker at verdien er den samme. De nøkkel felt kan være en nodebane som / config / dev / my_key.

5.1. Watchers

En annen interessant funksjon i Zookeeper er muligheten til å se på nøkler eller noder. Det lar oss lytte til endringer i konfigurasjonen og oppdatere applikasjonene våre uten å måtte distribuere på nytt.

La oss se hvordan eksemplet ovenfor ser ut når du bruker overvåkere:

CuratorFramework-klient = newClient () client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (klient); Strengnøkkel = getKey (); Streng forventet = "min_verdi"; async.create (). forPath (nøkkel); Listeendringer = ny ArrayList (); async.watched () .getData () .forPath (nøkkel) .event () .thenAccept (WatchEvent -> {prøv {changes.add (ny String (client.getData () .forPath (WatchEvent.getPath ()))) ;} fange (Unntak e) {// mislykkes ...}}); // Sett dataverdi for nøkkelen async.setData () .forPath (nøkkel, forventet.getBytes ()); venter på () .tiltil (() -> hevder at (endrer.størrelse ()). erEqualTo (1));

Vi konfigurerer seeren, angir dataene og bekrefter deretter at den overvåkede hendelsen ble utløst. Vi kan se en node eller et sett med noder samtidig.

6. Sterkt typede modeller

Zookeeper fungerer primært med byte-arrays, så vi må serialisere og deserialisere dataene våre. Dette gir oss en viss fleksibilitet til å jobbe med alle serierbare forekomster, men det kan være vanskelig å vedlikeholde.

For å hjelpe her legger Curator til konseptet med typede modeller som delegerer serialisering / deserialisering og lar oss jobbe med typene våre direkte. La oss se hvordan det fungerer.

Først trenger vi et serialiseringsrammeverk. Curator anbefaler å bruke Jackson-implementeringen, så la oss legge Jackson-avhengigheten til vår pom.xml:

 com.fasterxml.jackson.core jackson-databind 2.9.4 

La oss nå prøve å fortsette vår tilpassede klasse HostConfig:

offentlig klasse HostConfig {private strengnavn; privat int port; // getters og setters}

Vi må gi modellspesifikasjonskartleggingen fra HostConfig klasse til en bane, og bruk den modellerte rammeverket som tilbys av Apache Curator:

ModelSpec mySpec = ModelSpec.builder (ZPath.parseWithIds ("/ config / dev"), JacksonModelSerializer.build (HostConfig.class)) .build (); CuratorFramework-klient = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (klient); ModeledFramework modeledClient = ModeledFramework.wrap (async, mySpec); modeledClient.set (nytt HostConfig ("vertsnavn", 8080)); modeledClient.read () .whenComplete ((verdi, e) -> {hvis (e! = null) {fail ("Kan ikke lese vertskonfigurasjon", e);} annet {assertThat (verdi) .isNotNull (); assertThat ( value.getHostname ()). isEqualTo ("host-name"); assertThat (value.getPort ()). isEqualTo (8080);}});

De nårFullstendig () metode når du leser stien / config / dev vil returnere HostConfig eksempel i Zookeeper.

7. Oppskrifter

Zookeeper gir denne retningslinjen for implementering løsninger på høyt nivå eller oppskrifter som ledervalg, distribuerte låser eller delte tellere.

Apache Curator gir en implementering for de fleste av disse oppskriftene. For å se hele listen, besøk dokumentasjonen for kuratoroppskrifter.

Alle disse oppskriftene er tilgjengelige i en egen modul:

 org.apache.curator kurator-oppskrifter 4.0.1 

La oss hoppe rett inn og begynne å forstå disse med noen enkle eksempler.

7.1. Ledervalg

I et distribuert miljø kan det hende vi trenger en master- eller ledernode for å koordinere en kompleks jobb.

Slik ser bruken av ledervalgoppskriften i kurator ut:

CuratorFramework-klient = newClient (); client.start (); LeaderSelector leaderSelector = ny LeaderSelector (klient, "/ mutex / select / leader / for / job / A", ny LeaderSelectorListener () {@Override public void stateChanged (CuratorFramework client, ConnectionState newState) {} @Override public void takeLeadership (CuratorFramework client) ) kaster Unntak {}}); // bli medlem gruppeleder Selector.start (); // vent til jobben A er gjort blant alle medlemmene leaderSelector.close ();

Når vi starter ledervelgeren, blir vår node med i en medlemsgruppe innenfor banen / mutex / velg / leder / for / jobb / A.. Når node vår blir leder, blir ta ledelse metoden vil bli påkalt, og vi som ledere kan gjenoppta jobben.

7.2. Delt lås

Delt lås oppskrift handler om å ha en fullt distribuert lås:

CuratorFramework-klient = newClient (); client.start (); InterProcessSemaphoreMutex sharedLock = ny InterProcessSemaphoreMutex (klient, "/ mutex / prosess / A"); sharedLock.acquire (); // behandle A sharedLock.release ();

Når vi anskaffer låsen, sørger Zookeeper for at det ikke er noen annen applikasjon som får samme lås samtidig.

7.3. Teller

The Counters oppskrift koordinerer en delt Heltall blant alle klientene:

CuratorFramework-klient = newClient (); client.start (); SharedCount-teller = ny SharedCount (klient, "/ counters / A", 0); counter.start (); counter.setCount (counter.getCount () + 1); assertThat (counter.getCount ()). erEqualTo (1);

I dette eksemplet lagrer Zookeeper Heltall verdi i banen / tellere / A og initialiserer verdien til 0 hvis stien ikke er opprettet ennå.

8. Konklusjon

I denne artikkelen har vi sett hvordan du bruker Apache Curator til å koble til Apache Zookeeper og dra nytte av hovedfunksjonene.

Vi har også introdusert noen av hovedoppskriftene i Curator.

Som vanlig kan du finne kilder på GitHub.


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