Inleiding tot Apache Curator

1. Inleiding

Apache Curator is een Java-client voor Apache Zookeeper, de populaire coördinatiedienst voor gedistribueerde applicaties.

In deze tutorial introduceren we enkele van de meest relevante functies die door curator worden geboden:

  • Verbindingsbeheer - het beheren van verbindingen en beleid voor opnieuw proberen
  • Async - verbetering van de bestaande client door async-mogelijkheden toe te voegen en het gebruik van Java 8-lambda's
  • Configuratiebeheer - met een gecentraliseerde configuratie voor het systeem
  • Sterk getypeerde modellen - werken met getypte modellen
  • Recepten - uitvoering van leidersverkiezingen, gedistribueerde sloten of loketten

2. Vereisten

Om te beginnen wordt het aanbevolen om de Apache Zookeeper en zijn functies snel te bekijken.

Voor deze zelfstudie gaan we ervan uit dat er al een zelfstandige Zookeeper-instantie actief is 127.0.0.1:2181; hier vindt u instructies voor het installeren en uitvoeren ervan, als u net begint.

Eerst moeten we de afhankelijkheid curator-x-async toevoegen aan onze pom.xml:

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

De nieuwste versie van Apache Curator 4.X.X is moeilijk afhankelijk van Zookeeper 3.5.X die momenteel nog in bèta is.

En dus gaan we in dit artikel de momenteel nieuwste stabiele Zookeeper 3.4.11 gebruiken.

We moeten dus de Zookeeper-afhankelijkheid uitsluiten en de afhankelijkheid voor onze Zookeeper-versie toevoegen aan onze pom.xml:

 org.apache.zookeeper dierenverzorger 3.4.11 

Raadpleeg deze link voor meer informatie over compatibiliteit.

3. Verbindingsbeheer

Het basisgebruik van Apache Curator is verbinding maken met een actieve Apache Zookeeper-instantie.

De tool biedt een fabriek om verbindingen met Zookeeper tot stand te brengen met behulp van beleid voor opnieuw proberen:

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

In dit korte voorbeeld proberen we het 3 keer opnieuw en wachten we 100 ms tussen nieuwe pogingen in geval van verbindingsproblemen.

Eenmaal verbonden met Zookeeper met behulp van de CuratorFramework client, kunnen we nu door paden bladeren, gegevens ophalen / instellen en in wezen communiceren met de server.

4. Async

De Curator Async-module omvat het bovenstaande CuratorFramework client om niet-blokkerende mogelijkheden te bieden met behulp van de CompletionStage Java 8 API.

Laten we eens kijken hoe het vorige voorbeeld eruitziet met de Async-wrapper:

int sleepMsBetweenRetries = 100; int maxRetries = 3; RetryPolicy retryPolicy = nieuwe RetryNTimes (maxRetries, sleepMsBetweenRetries); CuratorFramework client = CuratorFrameworkFactory .newClient ("127.0.0.1:2181", retryPolicy); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (client); AtomicBoolean bestaat = nieuwe AtomicBoolean (false); async.checkExists () .forPath ("/") .thenAcceptAsync (s -> exist.set (s! = null)); wacht (). tot (() -> assertThat (exist.get ()). isTrue ());

Nu de checkExists () operatie werkt in asynchrone modus en blokkeert de hoofdthread niet. We kunnen ook acties na elkaar koppelen met behulp van de thenAcceptAsync () methode, die de CompletionStage API gebruikt.

5. Configuratiebeheer

In een gedistribueerde omgeving is een van de meest voorkomende uitdagingen het beheren van gedeelde configuratie tussen veel applicaties. We kunnen Zookeeper gebruiken als een datastore waar we onze configuratie kunnen bewaren.

Laten we een voorbeeld bekijken met Apache Curator om gegevens op te halen en in te stellen:

CuratorFramework-client = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (client); String key = getKey (); String verwacht = "mijn_waarde"; client.create (). forPath (sleutel); async.setData () .forPath (sleutel, verwacht.getBytes ()); AtomicBoolean isEquals = nieuwe AtomicBoolean (); async.getData () .forPath (sleutel) .thenAccept (data -> isEquals.set (nieuwe String (data) .equals (verwacht))); wacht (). tot (() -> assertThat (isEquals.get ()). isTrue ());

In dit voorbeeld maken we het knooppuntpad, stellen we de gegevens in Zookeeper in en herstellen we het door te controleren of de waarde hetzelfde is. De sleutel veld kan een knooppuntpad zijn, zoals / config / dev / my_key.

5.1. Kijkers

Een andere interessante functie in Zookeeper is de mogelijkheid om toetsen of knooppunten te bekijken. Het stelt ons in staat te luisteren naar wijzigingen in de configuratie en onze applicaties bij te werken zonder opnieuw te hoeven implementeren.

Laten we eens kijken hoe het bovenstaande voorbeeld eruitziet bij het gebruik van watchers:

CuratorFramework-client = newClient () client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (client); String key = getKey (); String verwacht = "mijn_waarde"; async.create (). forPath (sleutel); Lijstwijzigingen = nieuwe ArrayList (); async.watched () .getData () .forPath (key) .event () .thenAccept (watchedEvent -> {probeer {changes.add (new String (client.getData () .forPath (watchedEvent.getPath ()))) ;} catch (uitzondering e) {// fail ...}}); // Stel de gegevenswaarde in voor onze sleutel async.setData () .forPath (sleutel, verwacht.getBytes ()); await () .until (() -> assertThat (changes.size ()). isEqualTo (1));

We configureren de watcher, stellen de gegevens in en bevestigen vervolgens dat de bekeken gebeurtenis is geactiveerd. We kunnen één knooppunt of een reeks knooppunten tegelijk bekijken.

6. Sterk getypeerde modellen

Zookeeper werkt voornamelijk met byte-arrays, dus we moeten onze gegevens serialiseren en deserialiseren. Dit geeft ons enige flexibiliteit om met elke serialiseerbare instantie te werken, maar het kan moeilijk te onderhouden zijn.

Om hier te helpen, voegt Curator het concept van getypte modellen toe delegeert de serialisatie / deserialisatie en stelt ons in staat om rechtstreeks met onze typen te werken. Laten we eens kijken hoe dat werkt.

Ten eerste hebben we een serializer-framework nodig. Curator raadt aan om de Jackson-implementatie te gebruiken, dus laten we de Jackson-afhankelijkheid toevoegen aan onze pom.xml:

 com.fasterxml.jackson.core jackson-databind 2.9.4 

Laten we nu proberen onze aangepaste les voort te zetten HostConfig:

openbare klasse HostConfig {hostnaam van privéstring; privé int poort; // getters en setters}

We moeten de modelspecificatie-toewijzing leveren vanuit de HostConfig class naar een pad, en gebruik de gemodelleerde framework-wrapper die wordt geleverd door Apache Curator:

ModelSpec mySpec = ModelSpec.builder (ZPath.parseWithIds ("/ config / dev"), JacksonModelSerializer.build (HostConfig.class)) .build (); CuratorFramework-client = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (client); ModeledFramework modeledClient = ModeledFramework.wrap (async, mySpec); modeledClient.set (nieuwe HostConfig ("hostnaam", 8080)); modeledClient.read () .whenComplete ((waarde, e) -> {if (e! = null) {fail ("Kan hostconfiguratie niet lezen", e);} else {assertThat (waarde) .isNotNull (); assertThat ( value.getHostname ()). isEqualTo ("hostnaam"); ​​assertThat (waarde.getPort ()). isEqualTo (8080);}});

De wanneer voltooid () methode bij het lezen van het pad / config / dev retourneert de HostConfig bijvoorbeeld in Zookeeper.

7. Recepten

Zookeeper biedt deze richtlijn om te implementeren oplossingen op hoog niveau of recepten zoals leidersverkiezingen, gedistribueerde sloten of gedeelde loketten.

Apache Curator biedt een implementatie voor de meeste van deze recepten. Ga naar de documentatie van Curator Recepten om de volledige lijst te zien.

Al deze recepten zijn beschikbaar in een aparte module:

 org.apache.curator curator-recepten 4.0.1 

Laten we meteen beginnen en deze gaan begrijpen met enkele eenvoudige voorbeelden.

7.1. Verkiezing van leiders

In een gedistribueerde omgeving hebben we misschien één hoofd- of leiderknooppunt nodig om een ​​complexe taak te coördineren.

Dit is hoe het gebruik van het Leader Election-recept in Curator eruit ziet:

CuratorFramework-client = newClient (); client.start (); LeaderSelector leaderSelector = nieuwe LeaderSelector (client, "/ mutex / select / leader / for / job / A", nieuwe LeaderSelectorListener () {@Override public void stateChanged (CuratorFramework-client, ConnectionState newState) {} @Override public void takeLeadership (CuratorFram-client ) gooit uitzondering {}}); // word lid van de ledengroep leaderSelector.start (); // wacht tot de taak A is gedaan onder alle leden leaderSelector.close ();

Wanneer we de leider-selector starten, voegt ons knooppunt zich bij een ledengroep binnen het pad / mutex / select / leader / voor / job / A. Zodra ons knooppunt de leider wordt, wordt de leiderschap methode zal worden ingeroepen, en wij als leiders kunnen de baan hervatten.

7.2. Gedeelde sloten

Het Shared Lock-recept gaat over het hebben van een volledig gedistribueerd slot:

CuratorFramework-client = newClient (); client.start (); InterProcessSemaphoreMutex sharedLock = nieuwe InterProcessSemaphoreMutex (client, "/ mutex / process / A"); sharedLock.acquire (); // verwerk A sharedLock.release ();

Wanneer we het slot verkrijgen, zorgt Zookeeper ervoor dat geen enkele andere applicatie tegelijkertijd hetzelfde slot verkrijgt.

7.3. Tellers

Het recept van de tellers coördineert een gedeeld Geheel getal onder alle klanten:

CuratorFramework-client = newClient (); client.start (); SharedCount counter = nieuwe SharedCount (client, "/ counters / A", 0); counter.start (); counter.setCount (counter.getCount () + 1); assertThat (counter.getCount ()). isEqualTo (1);

In dit voorbeeld slaat Zookeeper het Geheel getal waarde in het pad / tellers / A en initialiseert de waarde naar 0 als het pad nog niet is aangemaakt.

8. Conclusie

In dit artikel hebben we gezien hoe u Apache Curator kunt gebruiken om verbinding te maken met Apache Zookeeper en te profiteren van de belangrijkste functies.

We hebben ook enkele van de belangrijkste recepten in Curator geïntroduceerd.

Zoals gewoonlijk zijn bronnen te vinden op GitHub.