Bevezetés az Apache kurátorba

1. Bemutatkozás

Az Apache Curator egy Java kliens az Apache Zookeeper számára, amely az elosztott alkalmazások népszerű koordinációs szolgáltatása.

Ebben az oktatóanyagban bemutatjuk a Kurátor által nyújtott legfontosabb funkciókat:

  • Connection Management - kapcsolatok kezelése és újrapróbálkozási házirendek
  • Async - a meglévő kliens javítása aszinkron képességek hozzáadásával és a Java 8 lambdas használatával
  • Konfigurációkezelés - központosított konfigurációval rendelkezik a rendszer számára
  • Erősen tipizált modellek - gépelt modellekkel dolgoznak
  • Receptek - vezetőválasztás végrehajtása, elosztott zárak vagy számlálók

2. Előfeltételek

Először is ajánlott egy gyors pillantást vetni az Apache Zookeeperre és annak jellemzőire.

Ehhez az oktatóanyaghoz feltételezzük, hogy már fut egy önálló Zookeeper-példány 127.0.0.1:2181; itt vannak utasítások a telepítéséhez és futtatásához, ha csak most kezded.

Először hozzá kell adnunk a kurátor-x-aszinkron függőséget a sajátunkhoz pom.xml:

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

Az Apache Curator 4.X.X legújabb verziója nagyon függ a Zookeeper 3.5.X-től amely jelenleg még béta állapotban van.

Tehát ebben a cikkben a jelenlegi legfrissebb stabil Zookeeper 3.4.11-et fogjuk használni.

Tehát ki kell zárnunk a Zookeeper függőséget, és hozzá kell adnunk a Zookeeper verziónk függőségét pom.xml:

 org.apache.zookeeper zookeeper 3.4.11 

A kompatibilitással kapcsolatos további információkért kérjük, olvassa el ezt a linket.

3. Kapcsolatkezelés

Az Apache Curator alapvető használati esete egy futó Apache Zookeeper példányhoz kapcsolódik.

Az eszköz biztosítja a gyár számára a kapcsolatok kiépítését a Zookeeperrel az újrapróbálkozási házirendek használatával:

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

Ebben a gyors példában háromszor próbálkozunk, és 100 ms-ot várunk az újrapróbálkozások között, ha kapcsolódási problémák merülnek fel.

Miután csatlakozott a Zookeeperhez a KurátorKeret kliens, most már tallózhatunk az utakon, adatokat szerezhetünk / állíthatunk be és lényegében kölcsönhatásba léphetünk a szerverrel.

4. Async

A Kurátor Async modul áttekinti a fentieket KurátorKeret kliens nem blokkoló képességek biztosítására a CompletionStage Java 8 API használatával.

Nézzük meg, hogyan néz ki az előző példa az Async csomagoló használatával:

int sleepMsBetweenRetries = 100; int maxRetries = 3; RetryPolicy retryPolicy = új RetryNTimes (maxRetries, sleepMsBetweenRetries); CuratorFramework client = CuratorFrameworkFactory .newClient ("127.0.0.1:2181", retryPolicy); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (kliens); AtomicBoolean létezik = új AtomicBoolean (hamis); async.checkExists () .forPath ("/") .theAcceptAsync (s -> létezik.készlet (s! = null)); várjon (). amíg (() -> assertThat (létezik.get ()). isTrue ());

Most a checkExists () A művelet aszinkron módban működik, nem blokkolja a fő szálat. A műveleteket egymás után is láncolhatjuk a thenAcceptAsync () metódus helyett, amely a CompletionStage API-t használja.

5. Konfigurációkezelés

Elosztott környezetben az egyik leggyakoribb kihívás a megosztott konfiguráció kezelése a sok alkalmazás között. A Zookeepert adattárként használhatjuk, ahol meg tudjuk őrizni a konfigurációt.

Lássunk egy példát az Apache Curator használatával az adatok megszerzéséhez és beállításához:

CuratorFramework kliens = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (kliens); Karakterlánc = getKey (); String várható = "saját_értékem"; client.create (). forPath (kulcs); async.setData () .forPath (kulcs, várható.getBytes ()); AtomicBoolean isEquals = új AtomicBoolean (); async.getData () .forPath (kulcs) .theAccept (adatok -> isEquals.set (új String (adatok) .egyenlő (várható))); várjon (). amíg (() -> assertThat (isEquals.get ()). isTrue ());

Ebben a példában létrehozzuk a csomópont elérési útját, beállítjuk az adatokat a Zookeeper alkalmazásban, majd helyreállítjuk, és ellenőrizzük, hogy az érték ugyanaz. A kulcs mező lehet egy csomópont útvonal, mint / config / dev / my_key.

5.1. Figyelők

A Zookeeper másik érdekes tulajdonsága a kulcsok vagy csomópontok figyelésének képessége. Ez lehetővé teszi számunkra, hogy újratelepítés nélkül meghallgassuk a konfiguráció változásait és frissítsük az alkalmazásokat.

Nézzük meg, hogyan néz ki a fenti példa figyelőberendezések használatakor:

CuratorFramework kliens = newClient () client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (kliens); Karakterlánc = getKey (); String várható = "saját_értékem"; async.create (). forPath (kulcs); Listaváltások = new ArrayList (); async.watched () .getData () .forPath (kulcs) .event () .thenAccept (watchEvent -> {try {changes.add (új karakterlánc (client.getData () .forPath (watchEvent.getPath ()))) ;} catch (e kivétel) {// sikertelen ...}}); // Adatérték beállítása az async.setData () .forPath kulcshoz (kulcs, várható.getBytes ()); wait () .until (() -> assertThat (changes.size ()). isEqualTo (1));

Konfiguráljuk a figyelőt, beállítjuk az adatokat, majd megerősítjük, hogy a figyelt esemény elindult. Egyszerre megnézhetünk egy csomópontot vagy csomópontkészletet.

6. Erősen tipizált modellek

A Zookeeper elsősorban a bájt tömbökkel dolgozik, ezért sorosítanunk és deszerializálnunk kell adatainkat. Ez némi rugalmasságot biztosít számunkra, hogy bármilyen serializálható példánnyal dolgozzunk, de nehéz fenntartani.

Itt segít a kurátor a gépelt modellek koncepcióját, amely átruházza a sorosítást / deserializációt, és lehetővé teszi számunkra, hogy közvetlenül a típusainkkal dolgozzunk. Lássuk, hogyan működik.

Először is szükségünk van egy sorosító keretrendszerre. A kurátor javasolja a Jackson implementáció használatát, ezért adjuk hozzá a Jackson függőséget pom.xml:

 com.fasterxml.jackson.core jackson-databind 2.9.4 

Most próbáljuk meg kitartani az egyéni osztályunkat HostConfig:

public class HostConfig {private String hosztnév; privát int kikötő; // szerelők és beállítók}

Meg kell adnunk a modell specifikáció leképezését a HostConfig osztályt egy elérési útra, és használja az Apache Curator által biztosított modellezett keretrendszert:

ModelSpec mySpec = ModelSpec.builder (ZPath.parseWithIds ("/ config / dev"), JacksonModelSerializer.build (HostConfig.class)) .build (); CuratorFramework kliens = newClient (); client.start (); AsyncCuratorFramework async = AsyncCuratorFramework.wrap (kliens); ModeledFramework modeledClient = ModeledFramework.wrap (async, mySpec); modeledClient.set (új HostConfig ("hosztnév", 8080)); modeledClient.read () .whenComplete ((value, e) -> {if (e! = null) {fail ("Nem olvasható a host config", e);} else {assertThat (érték) .isNotNull (); assertThat ( value.getHostname ()). isEqualTo ("host-name"); assertThat (value.getPort ()). isEqualTo (8080);}});

A whenComplete () módszer az útvonal olvasásakor / config / dev visszaadja a HostConfig például a Zookeeperben.

7. Receptek

A Zookeeper biztosítja ezt az irányelvet a megvalósításhoz magas szintű megoldások vagy receptek, mint például a vezetőválasztás, elosztott zárak vagy megosztott pultok.

Az Apache Kurátor a legtöbb ilyen recept megvalósítását biztosítja. A teljes lista megtekintéséhez keresse fel a Kurátor Receptek dokumentációját.

Mindezek a receptek külön modulban állnak rendelkezésre:

 org.apache.curator kurátor-receptek 4.0.1 

Ugorjunk jobbra, és kezdjük megérteni ezeket néhány egyszerű példával.

7.1. Vezetői választás

Elosztott környezetben szükségünk lehet egy fő vagy vezető csomópontra egy összetett feladat koordinálásához.

Így néz ki a Leader választási recept használata a kurátorban:

CuratorFramework kliens = newClient (); client.start (); LeaderSelector leaderSelector = új LeaderSelector (kliens, "/ mutex / select / leader / for / job / A", új LeaderSelectorListener () {@Override public void stateChanged (CuratorFramework client, ConnectionState newState) {} @OOrride public void takeLeadership (CuratorF ) dob Kivételt {}}); // csatlakozzon a tagok csoportjának vezetőjéhezSelector.start (); // várja meg, amíg az A feladatot elvégzik az összes tag között leaderSelector.close ();

Amikor elindítjuk a vezetőválasztót, a csomópontunk egy tagcsoporthoz csatlakozik az útvonalon belül / mutex / select / leader / for / job / A. Amint csomópontunk vezetővé válik, a takeLeadership módszert alkalmazzuk, és mi vezetőkként folytathatjuk a munkát.

7.2. Közös zárak

A Shared Lock recept arról szól, hogy van egy teljesen elosztott zár:

CuratorFramework kliens = newClient (); client.start (); InterProcessSemaphoreMutex sharedLock = új InterProcessSemaphoreMutex (kliens, "/ mutex / process / A"); sharedLock.acquire (); // nem csinál egy A sharedLock.release () folyamatot;

Amikor megszerezzük a zárat, a Zookeeper biztosítja, hogy nincs más alkalmazás, amely egyszerre megszerzi ugyanazt a zárat.

7.3. Pultok

A számlálók receptje egy megosztottat koordinál Egész szám az összes ügyfél között:

CuratorFramework kliens = newClient (); client.start (); SharedCount számláló = new SharedCount (kliens, "/ számlálók / A", 0); számláló.indítás (); counter.setCount (számláló.getCount () + 1); assertThat (counter.getCount ()). isEqualTo (1);

Ebben a példában a Zookeeper tárolja a Egész szám érték az útvonalon / számlálók / A és inicializálja az értéket 0 ha az út még nem jött létre.

8. Következtetés

Ebben a cikkben azt láttuk, hogyan lehet az Apache Curator használatával csatlakozni az Apache Zookeeperhez és kihasználni annak főbb szolgáltatásait.

Bevezettünk néhány fő receptet a Kurátorban.

Szokás szerint a források a GitHubon találhatók.