Nous utilisons la version Java 3.4.6 dans cet exemple. L'exemple est pratique pour tout le monde si vous ne comprenez pas après l'avoir appris.
La liaison Java Zookeeper pour le développement des applications est principalement composée de deux packages Java:
org.apache.zookeeper
org.apache.zookeeper.data
Le package org.apache.zookeeper se compose de la définition d'interface surveillée par ZooKeeper et divers gestionnaires de rappel pour Zookeeper. Il définit les classes principales de la bibliothèque de classe client ZooKeeper ainsi que les définitions statiques de nombreux types et états d'événements ZooKeeper. Le package org.apache.zookeeper.data définit les fonctionnalités liées aux registres de données (également appelés zNodes), tels que les listes de contrôle d'accès (ACL), les ID, les statistiques, etc.
L'org.apache.zookeeper.server, org.apache.zookeeper.server.quorum et org.apache.zookeeper.server.upgrade packages dans l'API Java Zookeeper fait partie de l'implémentation du serveur. Le package org.apache.zookeeper.client est utilisé pour interroger l'état du serveur ZooKeeper.
Préparez-vous à l'environnement de développement
Apache ZooKeeper est un logiciel complexe, il faut donc exécuter de nombreuses autres bibliothèques de classe. La bibliothèque de dépendances est incluse dans le répertoire LIB en tant que fichier JAR dans la distribution Zookeeper. Le nom de fichier de base de Zookeeper Jar est Zookeeper-3.4.6.jar, situé dans le répertoire domestique.
Pour développer une application Java Zookeeper, nous devons définir le chemin de classe sur le pot Zookeeper, et toutes les bibliothèques tierces dont dépend Zookeeper. Il y a un fichier zkenv.sh dans le répertoire bin, qui peut être utilisé pour définir ClassPath.
Nous devons définir le script comme suit et exécuter l'instruction suivante sur la ligne de commande:
$ Zoobindir = $ {zk_home} / bin $ source $ {zoobindir} /zkenv.shLa variable Shell ZK_HOME est définie sur le chemin pour installer ZooKeeper, dans mes paramètres, il est / usr / share / zookeeper. Après cela, la variable CLASSPATH est définie correctement, dans mon système comme ceci:
$ echo $ classpath /usr/share/zookeeper-3.4.6/bin/../build/classes: /usr/share/zookeeper-3.4.6/bin /../ build / lib / *. : /usr/share/zookeeper-3.4.6/bin /../ lib / slf4j-api-1.6.1.jar: /usr/share/zookeeper-3.4.6/bin /../ lib / netty-3.7.0.final.jar: /usr/share/zookeeper-3.4.6/bin /../ lib / log4j-1.16. : /usr/share/zookeeper-3.4.6/bin /../ lib / jline-0.9.94.jar: /usr/share/zookeeper-3.4.6/bin /../ zookeeper-3.4.6.jar: /usr/share/zookeeper-3.4.6/bin /../ src / Java / lib / *. : /usr/share/zookeeper-3.4.6/bin /../ conf:
Dans le système d'exploitation Windows, vous devez exécuter le script zkenv.cmd. Vous pouvez maintenant utiliser la variable ClassPath pour compiler et exécuter les programmes Java écrits à l'aide de l'API ZooKeeper. Le script zkenv.sh se trouve dans le fichier .bashrc du répertoire domestique dans Uni / Linux pour éviter de l'utiliser à chaque fois que la session Shell est démarrée.
Le deuxième premier programme de gardien de zoo
Pour introduire l'API Zookeeper Java, commençons par un programme très simple qui peut se connecter à l'instance ZooKeeper dans LocalHost et si la connexion réussit, elle imprimera une liste de Znodes sous le chemin racine de l'espace de noms Zookeeper.
Le code de ce programme est le suivant:
/ * Notre premier programme Zookeeper * / Importer java.io.ioException; Importer java.util.arraylist; import java.util.list; import org.apache.zookeeper.keerexception; import org.apache.zookeeper.zookeeper; public class hellozookeeper {public static vide main (string [] args) throws ioexception {stringport = hostport = hospit "localhost:2181";String zpath = "/";List <String> zooChildren = new ArrayList<String>();ZooKeeper zk = new ZooKeeper(hostPort, 2000, null);if (zk != null) {try {zooChildren = zk.getChildren(zpath, false);System.out.println("Znodes of '/': "); for (String Child: ZooChildren) {// imprime le childrensystem.out.println (enfant);}} catch (gardienAvant de construire et d'exécuter l'extrait de code précédent, voyons ce qu'il fait spécifiquement. Le code commence par l'instruction IMPORT. En utilisant ces instructions, nous importons les packages requis par chaque composant du programme. Comme mentionné précédemment, le package org.apache.zookeeper contient toutes les classes et interfaces requises par le client pour interagir avec le serveur Zookeeper. Après l'importation du package, une classe nommée Hellozookeeper est définie. Étant donné que nous nous connectons à l'instance ZooKeeper exécutée dans le même système, définissez l'hôte et les chaînes de port comme localhost: 2181 dans la méthode principale. La ligne de code zk = new ZooKeeper (Hostport, 2000, null) appelle le constructeur ZooKeeper, qui tente de se connecter au serveur ZooKeeper et renvoie une référence. Pour les programmes clients qui se connectent à l'instance de serveur ZooKeeper et maintiennent cette connexion, une session en temps réel est requise. Dans cet exemple, la référence renvoyée par l'objet ZK instanciée par le constructeur représente la session. L'API Zookeeper est construite autour de cette référence, et chaque appel de méthode nécessite une référence à exécuter.
Le constructeur de la classe Zookeeper utilise le code suivant pour créer une référence à l'instance Zookeeper:
ZooKeeper (String ConnectString, int sessionTimeout, Watcher Watcher)
Les paramètres utilisés sont les suivants:
ConnectString: hôte séparé des virgules: une liste des numéros de port, chacun correspondant à un serveur de gardien de zoo. Par exemple, 10.0.0.1:2001, 10.0.0.2:2002 et 10.0.0.3:2003 Représenter un hôte valide: des paires de correspondance de port pour les ensembles de gardien de zoo de trois nœuds. SessionTimeout: Ceci est le délai de session en millisecondes. C'est le moment où Zookeeper n'a pas obtenu de battement de cœur du client avant d'annoncer la fin de la session. Watcher: un objet Watcher qui est notifié s'il est créé lorsque l'état change et que les événements de nœud se produisent. Cet objet Watcher doit être créé séparément via une classe définie par l'utilisateur, qui implémente l'interface de l'observateur et passe l'objet instancié au constructeur ZooKeeper. Les demandes des clients peuvent recevoir des notifications de divers types d'événements, tels que les connexions manquantes, l'expiration des sessions, etc.
L'API Java Zookeeper définit un constructeur supplémentaire avec trois paramètres pour spécifier des opérations plus avancées. Le code est le suivant:
ZOOKEEPER (String ConnectString, int sessionTimeout, Watcher Watcher, boolean canbereadonly)
Dans le constructeur ci-dessus de la classe Zookeeper, si elle est définie sur true, le paramètre booléen canbereadonly permet au client créé de saisir le mode en lecture seule dans le cas de la partition réseau. Le mode en lecture seule est un scénario où le client ne trouve aucune majorité de serveurs, mais il existe un serveur de partition accessible pour s'y connecter en mode en lecture seule, ce qui permet de lire les demandes au serveur, tandis que les demandes d'écriture ne sont pas autorisées. Le client continue d'essayer de se connecter à la plupart des serveurs en arrière-plan tout en restant en lecture seule. Un serveur de partition n'est qu'un sous-ensemble du groupe Zookeeper, qui est formé en raison de l'allocation de réseau dans le cluster. La plupart des serveurs constituent la plupart des quorums dans l'ensemble.
Le constructeur suivant montre la définition de deux paramètres supplémentaires:
ZOOKEEPER (String ConnectString, int sessionTimeout, Watcher Watcher, Long SessionId, Byte [] SessionPasswd)
Ce constructeur permet à l'objet client ZooKeeper de créer deux paramètres supplémentaires:
SessionID: Dans le cas où le client se reconnecte au serveur Zookeeper, un ID de session spécifique peut être utilisé pour se référer à la session Session Précédente: Si la session spécifiée nécessite un mot de passe, vous pouvez le spécifier ici
Le constructeur suivant est une combinaison des deux premiers appels:
ZOOKEEPER (String ConnectString, int sessionTimeout, Watcher Watcher, Long SessionId, Byte [] SessionPasswd, boolean canbereadonly)
Ce constructeur est une combinaison des deux premiers appels, permettant la reconnexion à la session spécifiée avec le mode en lecture seule activée.
Note
La documentation détaillée de l'API Java pour la classe ZooKeeper peut être interrogée sur http://zookeeper.apache.org/doc/r3.4.6/api/index.html.
Maintenant, revenons à notre programme Zookeeper. Après avoir appelé le constructeur, si la connexion est réussie, nous obtiendrons une référence au serveur Zookeeper. Nous transmettons la référence à la méthode Getchildren via le code suivant:
zoochildren = zk.getchildren (zpath, false)
La méthode GetChildren (Chemin de chaîne, Watch Boolean) de la classe Zookeeper renvoie la liste des enfants de Znode sur le chemin donné. Nous itons simplement sur la liste renvoyée par cette méthode et imprimons la chaîne à la console.
Nommez le programme hellozookeeper.java et compilez notre programme comme suit:
$ javac -cp $ classpath hellozookeeper.java
Avant d'exécuter le programme, nous devons démarrer l'instance de serveur Zookeeper à l'aide de la commande suivante:
$ $ {Zk_home} /bin/zkserver.sh startExécutez le programme comme suit:
$ java -cp $ classpath hellozookeeper
L'exécuteur exécuteur imprimera un message de journal sur la console, affichant la version ZooKeeper, la version Java, Java ClassPath, Architecture Server, etc. Utilisé. Voici quelques-uns de ces messages journaux:
Les messages de journal générés par l'API Java Zookeeper sont très utiles pour le débogage. Il nous fournit des informations sur le client se connectant au serveur ZooKeeper, en établissant une session et d'autres antécédents. Les trois derniers messages de journal indiqués ci-dessus nous indiquent comment le client démarre la connexion à l'aide des paramètres spécifiés dans le programme et comment le serveur attribue l'ID de session au client après une connexion réussie.
Enfin, l'exécution du programme publie enfin ce qui suit dans la console:
Nous pouvons utiliser le shell Zookeeper pour vérifier l'exactitude du programme:
$ $ Zk_home / bin / zkcli.sh -server localhost
Félicitations! Nous avons juste écrit avec succès notre premier programme client ZooKeeper.
Deuxièmement, implémentez l'interface d'observation
ZooKeeper Watcher Survering permet aux clients de recevoir des notifications des serveurs ZooKeeper et de gérer ces événements lorsqu'ils se produisent. L'API Java Zookeeper fournit une interface publique appelée Watcher que la classe de gestionnaire d'événements clients doit implémenter pour recevoir des notifications d'événements sur les événements du serveur ZooKeeper. Programmatiquement, les applications utilisant ces clients gèrent ces événements en enregistrant des objets de rappel auprès du client.
Nous implémenterons l'interface de l'observateur pour gérer les événements générés par ZooKeeper lorsque les données associées à Znode sont modifiées.
L'interface Watcher est déclarée comme suit dans le package org.apache.zookeeper:
Watcher d'interface publique {processus void (événement WatchEdEvent);}Pour démontrer le Znode Data Monitor (Watcher), il existe deux classes Java: DataWatcher et DataUpDater. Le DataWatcher s'exécutera tout le temps et écoutera les événements NODEDATACHANGE du serveur ZooKeeper dans le chemin Znode spécifié / MyConfig. La classe DataUpDater mettra à jour périodiquement les champs de données de ce chemin Znode, qui générera des événements, et lors de la réception de ces événements, la classe DataWatcher imprimera les données modifiées en console.
Ce qui suit est le code de la classe DataWatcher.java:
Importer java.io.ioException; import org.apache.zookeeper.createMode; import org.apache.zookeevent.keerexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.zoodefs; import org.apache.zookeeper. DataWatcher implémente Watcher, Runnable {private static String hostport = "localhost: 2181"; private static string zOodatapath = "/ myconfig"; byte zoo_data [] = null; zookeeper zk; public dataWatcher () {try {zk = new Zookeeper (hostport, 2000, this); if (zk) Znode si cela n'existe pas, avec le code suivant: if (zk.exists (zoodatapath, this) == null) {zk.create (zoodatapath, "" .getbytes (), zoods.ids.open_acl_unsafe, createMode.peSersistent);}} catch (keerexception | interruptedException a) gens du Znode à la console: System.out.printf ("/ ncurrent data @ zk path% s:% s", zoodatapath, zstring);} @ overRidepublic void process (watchedevent event) {System.out.printf ("/ nevent reçoit:% s", event.tostring ()); // nous ne traiterons que les événements de Typea (event.getType() == Event.EventType.NodeDataChanged) {try {printData();} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}} public static void main(String[] args)throws InterruptedException, KeeperException {DataWatcher dataWatcher = new DataWatcher (); datawatcher.printdata (); dataWatcher.run ();} public void run () {try {synchronisé (this) {while (true) {wait ();}}} catch (interruptedException e) {e.printStackTrace (); thread.currentThread (). Interrupt ();}}}Jetons un coup d'œil au code de la classe dataWatcher.java pour comprendre l'implémentation d'un moniteur Zookeeper. La classe publique de DataWatcher implémente l'interface d'observation et l'interface Runnable, et a l'intention d'exécuter le moniteur en tant que thread. La méthode principale crée une instance de la classe DataWatcher. Dans le code précédent, le constructeur de DataWatcher tente de se connecter à une instance de gardien de zoo exécutant sur le localhost. Si la connexion est réussie, nous utilisons le code suivant pour vérifier si le chemin Znode / MyConfig existe:
if (zk.exists (zoodatapath, this) == null) {Si le Znode n'existe pas dans l'espace de noms Zookeeper, l'appel de la méthode existant renvoie NULL et essayez de le créer en tant que Znode persistant en utilisant le code comme suit:
zk.create (zoodatapath, "" .getBytes (), zoods.ids.open_acl_unsafe, createMode.persistent);
Ensuite, la méthode de processus, qui est déclarée dans l'interface de l'observateur de org.apache.zookeeper et implémentée par la classe DataWatcher en utilisant le code suivant:
Processus de vide public (événement WatchEdEvent) {Pour plus de simplicité, dans la méthode du processus, les événements reçus de l'instance de gardien de zoo sont imprimés et les seuls événements de type nodedatachanged sont traités comme suit:
if (event.getType () == Event.EventType.NodeDatachanged)
Lorsque une mise à jour ou un changement se produit dans le champ de données du chemin Znode / MyConfig et qu'un événement de type NodeDatachanged est reçu, la méthode PrintData est appelée pour imprimer le contenu actuel du Znode. Lors de l'exécution d'un appel GetData sur ZNODE, nous reformulons un moniteur, qui est le deuxième paramètre de la méthode, comme indiqué dans le code suivant:
zoo_data = zk.getData (zoodatapath, this, null);
Les événements de surveillance sont des déclencheurs uniques envoyés aux clients qui définissent la surveillance. Afin de recevoir en continu d'autres notifications d'événements, les clients doivent réinitialiser le moniteur.
DataUpDater.java est une classe simple qui se connecte à l'instance ZooKeeper exécutant le LocalHost et met à jour le champ de données du Path Znode / MyConfig avec une chaîne aléatoire. Ici, nous choisissons de mettre à jour le ZNODE avec une chaîne Universal Unique Identifier (UUID), car les appels du générateur UUID ultérieur garantissent la génération de chaînes uniques.
Le code de classe DataUpDater.java est le suivant:
import java.io.ioException; import java.util.uuid; import org.apache.zookeeper.keerexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper. "LocalHost: 2181"; chaîne statique privée zoodatapath = "/ myconfig"; zookeeper zk; public dataupDater () lève ioException {try {zk = new ZooKeeper (Hostport, 2000, this);} catch (ioException e) {e.printStackTrace ();}} // Mise à jour le znode Path / MyconFig / 5 UUID String.Public void run () lance InterruptedException, gardienException {while (true) {String uUid = uUid.randomuuid (). ToString (); byte zoo_data [] = uuid.getbytes (); zk.setdata (zoodatapath, zoo_data, -1); try {witer. // sommeil pendant 5 secondes} catch (InterruptedException e) {thread.currentThread (). Interrupt ();}}} public static void Main (String [] args) throwsioException, interruptedException, keeprexception {dataupdater dataupdater = new DataupDater (); dataupdater.run ();} @ sweroïdepublic-voide procédé (dataupdater.run ();} @ sweety {System.out.printf ("/ nevent reçu:% s", event.toString ());}}Le code ci-dessus fait déclencher le serveur Zookeeper un événement nodeDatachanged. Étant donné que DataWatcher définit la surveillance de ce chemin Znode, il reçoit des notifications d'événements de changement de données. Il récupère ensuite les données mises à jour, réinitialise la surveillance et imprime les données sur la console.
Utilisez la commande suivante pour compiler les classes DataWatcher et DataupDater:
$ javac cp $ classpath datawatcher.java $ javac cp $ classpath dataupdater.java
Pour exécuter le programme Monitor and Update, deux fenêtres terminales doivent être ouvertes. Je veux d'abord exécuter le moniteur car il crée le Znode de / myconfig (s'il n'a pas été créé dans l'espace de noms ZooKeeper). Avant d'exécuter le moniteur, assurez-vous que le serveur Zookeeper fonctionne sur l'hôte local.
Dans l'une des fenêtres du terminal, exécutez la classe Watcher en exécutant la commande suivante:
$ java cp $ classpath dataWatcher
Sortir un message similaire à celui illustré dans la capture d'écran suivante:
Comme indiqué dans la capture d'écran précédente, le PATH ZNODE / MYCONFIG est créé par la classe DataWatcher. Il imprime également le contenu du Znode, mais pas dans la console, car nous ne définissons aucune donnée lors de la création du Znode. Lorsque ZNODE est créé, le moniteur de la classe reçoit une notification d'événement de type NodeCreated, qui est imprimé dans la console. La classe DataWatcher continue d'exécuter et écoute les événements sur le nœud / myconfig du serveur ZooKeeper.
Exécutons la classe DataUpDater dans une autre fenêtre de terminal:
$ java -cp $ classpath dataupDater
Après avoir enregistré le message de journal spécifique au gardien de zoo initial à la console, la classe DataUpDater s'exécute sans inciter. Il définit une nouvelle chaîne UUID dans le champ de données du ZooKeeper Path / MyConfig. Alors, voyez que toutes les 5 secondes, la sortie affichée dans la capture d'écran ci-dessous est imprimée dans la fenêtre du terminal exécutant Datawatch:
DataWatcher peut également être testé à l'aide du shell ZooKeeper. Continuez à exécuter la classe DataWatcher dans le terminal comme précédemment, et appelez le shell ZooKeeper dans un autre terminal et exécutez la commande affichée dans la capture d'écran suivante:
Dans le terminal où est en cours d'exécution, le message suivant est imprimé:
Trois exemples - moniteur de cluster
Les services populaires fournis via Internet, tels que les e-mails, les plates-formes de services de fichiers, les jeux en ligne, etc., sont desservies par des centaines ou des milliers de serveurs qui sont très disponibles dans plusieurs centres de données, qui sont souvent séparés géographiquement. Dans un tel cluster, certains nœuds de serveur dédiés sont configurés pour surveiller l'activité des serveurs qui sont hôtes ou applications dans le réseau de production. Dans un environnement de cloud computing, ces nœuds de surveillance qui sont également utilisés pour gérer l'environnement cloud sont appelés contrôleurs de cloud. Un travail important de ces nœuds de contrôleur consiste à détecter les défaillances dans les serveurs de production en temps réel et à informer les administrateurs en conséquence, et à prendre les mesures nécessaires telles que l'échec des applications sur le serveur échoué vers un autre serveur, garantissant la tolérance aux défauts et la haute disponibilité.
Dans cette section, nous utiliserons l'API du client Java Zookeeper pour développer un modèle de moniteur de cluster distribué minimaliste. L'utilisation du concept éphémère Znode de Zookeeper pour construire ce modèle de surveillance est assez simple et élégant, comme décrit dans les étapes suivantes:
Chaque serveur de production exécute un client Zookeeper en tant que démon. Ce processus se connecte au serveur ZooKeeper et crée un Znode éphémère avec un nom (de préférence son nom de réseau ou nom d'hôte) sous le chemin prédéfini de l'espace de noms / zookeeper (tel que / membres). Le nœud Cloud Controller exécute le processus ZooKeeper Monitor, qui surveille les chemins / membres et écoute les événements de type NodeChildRenchanged. Ce processus de moniteur s'exécute en tant que service ou démon, et définit ou réinitialise la surveillance sur le chemin, et implémente sa logique pour appeler les modules appropriés pour prendre les mesures nécessaires pour surveiller les événements. Maintenant, si le serveur de production est arrêté en raison d'une défaillance matérielle ou d'un crash logiciel, le processus client ZooKeeper est terminé, provoquant la résiliation de la session entre le serveur et le service ZooKeeper. Étant donné que les propriétés du Znode éphémère sont uniques, le service ZooKeeper supprimera automatiquement le Znode dans le chemin / les membres chaque fois que la connexion du client est fermée. La suppression de Znode dans le chemin soulève l'événement Nodechildrenchanged, de sorte que le processus d'observateur dans le contrôleur de cloud est notifié. En appelant la méthode Getchildren dans le chemin / les membres, vous pouvez déterminer quel nœud de serveur a été fermé. Le nœud de contrôleur peut ensuite prendre des mesures appropriées, telles que l'exécution de la logique de récupération pour redémarrer le service échoué dans un autre serveur. Cette logique peut être conçue pour fonctionner en temps réel, garantissant des services d'arrêt près de zéro et des services hautement disponibles.
Pour implémenter ce modèle de surveillance des cluster, nous développerons deux classes Java. La classe ClusterMonitor exécutera en continu le moniteur pour surveiller les chemins / membres de l'arborescence Zookeeper. Après avoir traité l'événement surélevé, nous imprimerons la liste Znode dans la console et réinitialiserons la surveillance. Un autre clusterClient de classe démarrera la connexion au serveur ZooKeeper et créera un Znode éphémère sous / membres.
Pour simuler un cluster avec plusieurs nœuds, nous commençons plusieurs clients sur le même ordinateur et créons un Znode éphémère en utilisant l'ID de processus du processus client. En affichant l'identité du processus, la classe ClusterMonitor peut déterminer quel processus client a été fermé et quels processus sont toujours là. Dans les cas pratiques, les processus clients créent généralement un Znode éphémère en utilisant le nom d'hôte du serveur en cours d'exécution. Les codes source de ces deux classes sont présentés ci-dessous.
La classe ClusterMonitor.java est définie comme suit:
Importer java.io.ioException; import java.util.list; import org.apache.zookeeper.createMode; import org.apache.zookeeper.keerexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper. org.apache.zookeeper.zookeeper; public classe ClusterMonitor implémente Runnable {private static String adhésion à la chaîne = "/ membres"; private final ConnectionWatcher; True; Private Final Watcher Childrenwatcher; String Hostport) lance (new) Wather () InterruptedException, GendException {ConnectionWather = Wather () Wather () {@OverRidePublic void Process (WatchEdEvent Event) {if (event.getType () == watcher.event.eventType.none && event.getState () == watcher.event.keeperstate.syncconnected) {System.out.printf ("/ nevent reçu:% s", event.tostring ());}}}; Watcher () {@OverRidePublic void Process (WatchEdEvent Event) {System.out.printf ("/ nevent reçoit:% s", event.toString ()); if (event.getType () == Event.EventType.NodeChildRenchanged) {Try {// Get Current List of Child Znode, // RESET THE WORDLIST <String> ZK. Adhipshiproot, this); wall ("!! Cluster Adhip Change !!!"); wall ("membres:" + enfants);} catch (gardien de gardien E) {Thread New RuntimeException (e);} Catch (InterruptedException e) {Thread.currentThread (). Interrupt (); Alive = false; Throw RuntimeException (e);}}}}}} 2000, ConnectionWatcher); // Assurez-vous que le parent Znode existe (zk.exists (membre, false) == null) {zk.create (membre, "ClusterMonitorroot" .getBytes (), ids.open_acl_unsafe, Creemode.Persistent);} // définir une montre sur le parent znodelist <cragine zk.getChildren (Adhipphiproot, Childrenwatcher); System.err.println ("membres:" + enfants);} public synchronisé void close () {try {zk.close ();} catch (interruptedException e) {e.printstacktrace ();}} public Void Wall (String Message) {System.out.out.Printf (" Message);} public void run () {try {synchronisé (this) {while (vif) {wait ();}}} catch (InterruptedException e) {e.printStackTrace (); thread.currentThread (). Interrupt ();} enfin {this.close ();}} public static Void main InterruptedException, gardienException {if (args.length! = 1) {System.err.println ("usage: ClusterMonitor <host: port>"); System.exit (0);} string hostport = args [0]; new ClusterMonitor (hostport) .run ();}}La classe ClusterClient.java est définie comme suit:
Importer java.io.ioException; import java.lang.management.managementfactory; import org.apache.zookeeper.createmode; import org.apache.zookeeper.keerexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper. org.apache.zookeeper.zookeeper; public class clusterClient implémente observer, runnable {private static string linghehiproot = "/ membres"; zookeeper zk; public clusterClient (string hostport, long pid) {String processId = pid.toString (); try {zk = new zookeeper (hostort, 2000, this);} capture (ioexection e) gens void close () {try {zk.close ();} catch (InterruptedException e) {e.printStackTrace ();}} @ OverRidepublic void Process (watchdevevent Event) {System.out.printf ("/ nevent reçue:% s", event.toString ();} public void run () {Try {synchronized (this);}) {wait ();}}} catch (interruptedException e) {e.printStackTrace (); thread.currentThread (). Interrupt ();} enfin {this.close ();}} public static void main (String [] args) {if (args.Lengthre <Host: port> "); System.exit (0);} string hostport = args [0]; // Obtenez le processus idString name = ManagementFactory.getRuntiMemXBean (). GetName (); int index = name.indexof ('@'); new ClusterClient (hospitalport, name.subString (0, index)); new ClusterClient (hospitalport, hostport, processId) .run ();}}Utilisez la commande suivante pour compiler ces deux classes:
$ javac -cp $ classpath clustermonitor.java $ javac -cp $ classpath clusterclient.java
Pour exécuter le modèle de surveillance des cluster, ouvrez deux bornes. Dans l'un des terminaux, exécutez la classe ClusterMonitor. Dans un autre terminal, plusieurs instances sont exécutées en exécutant la classe ClusterClient en arrière-plan.
Dans le premier terminal, exécutez la classe ClusterMonitor:
$ Java -CP $ CLASSPATH CLUSTERMORNOLOCALHOST: 2181
Comme indiqué dans l'exemple précédent, vous voyez le message de journal de débogage de l'API client. Enfin, la classe ClusterMonitor commence à surveiller l'événement et à entrer le contenu suivant:
Exécutez maintenant cinq instances de la classe ClusterClient pour simuler cinq nœuds d'un cluster. ClusterClient crée un Znode éphémère en utilisant son propre ID de processus dans le chemin / les membres de l'arborescence Zookeeper:
$ java -cp $ classpath clusterclient localhost: 2181 2> & 1> / dev / null & [1] 4028 $ java -cp $ classpath clusterclient localhost: 2181 2> & 1> / dev / null & [2] 4045 $ java -cp $ classpath & [$ $ $. java -cp $ classpath clusterClient localhost: 2181 2> & 1> / dev / null & [4] 4072 $ java -cp $ classpath clusterClient localhost: 2181 2> & 1> / dev / null & [5] 4084
En correspondant à cela, il sera observé que la classe ClusterMonitor détecte ces nouvelles instances de classe ClusterClient, car il s'agit de surveiller les événements sur le chemin / les membres de l'arborescence Zookeeper. Cela simule un événement de jonction de nœud dans un vrai cluster. La sortie peut être vue dans le terminal de la classe ClusterMonitor, qui est similaire à ce qui est montré dans la capture d'écran ci-dessous:
Maintenant, si un processus ClusterClient.java est tué, la session qu'elle maintient avec le serveur ZooKeeper sera terminée. Par conséquent, le Znode éphémère créé par le client sera supprimé. La suppression déclenchera l'événement Nodechildrenchanged, qui sera capturé par la classe ClusterMonitor. Cela simule un scénario où un nœud quitte dans le cluster.
Termons le processus ClusterClient avec ID 4084:
$ kill -9 4084
La capture d'écran suivante montre la sortie dans le terminal de la classe ClusterMonitor. Il répertorie les processus actuellement disponibles et leurs ID de processus qui imitent le serveur en temps réel:
L'exemple de mise en œuvre du modèle de surveillance de cluster simple et élégant ci-dessus montre la véritable puissance de Zookeeper. Sans Zookeeper, développer un tel modèle qui peut surveiller l'activité des nœuds en temps réel serait une véritable tâche intimidante.