Usamos a versão Java 3.4.6 neste exemplo. O exemplo é conveniente para todos discutirem se você não entende depois de aprendê -lo.
A ligação Java do Zookeeper para o desenvolvimento de aplicativos é composta principalmente por dois pacotes Java:
org.apache.zookeeper
org.apache.zookeeper.data
O pacote org.apache.zookeeper consiste na definição de interface monitorada pelo Zookeeper e vários manipuladores de retorno de chamada para o Zookeeper. Ele define as principais classes da biblioteca de classes de clientes do Zookeeper, bem como definições estáticas de muitos tipos e estados de eventos do Zookeeper. O pacote org.apache.zookeeper.data define recursos relacionados aos registros de dados (também conhecidos como Znodes), como listas de controle de acesso (ACLs), IDs, estatísticas, etc.
O org.apache.zookeeper.server, org.apache.zookeeper.server.quorum e org.apache.zookeeper.server.upgrade Os pacotes na API Java Zookeeper fazem parte da implementação do servidor. O pacote org.apache.zookeeper.client é usado para consultar o status do servidor Zookeeper.
Prepare -se para o ambiente de desenvolvimento
O Apache Zookeeper é um software complexo, por isso requer executar muitas outras bibliotecas de classes. A biblioteca de dependência está incluída no diretório LIB como um arquivo JAR na distribuição do Zookeeper. O nome do arquivo do Jar Core Zookeeper é Zookeeper-3.4.6.jar, localizado no diretório doméstico.
Para desenvolver um aplicativo Java Zookeeper, devemos definir o caminho de classe no Jar Zookeeper e todas as bibliotecas de terceiros das quais o Zookeeper depende. Existe um arquivo zkenv.sh no diretório da bin, que pode ser usado para definir o ClassPath.
Precisamos definir o script da seguinte maneira e executar a seguinte declaração na linha de comando:
$ Zoobindir = $ {zk_home}/bin $ fonte $ {zoobindir} /zkenv.shA variável shell zk_home está definida como o caminho para instalar o Zookeeper, nas minhas configurações é/usr/share/zookeeper. Depois disso, a variável de pista de classe é definida corretamente, no meu sistema como este:
$ echo $CLASSPATH /usr/share/zookeeper-3.4.6/bin/../build/classes :/usr/share/zookeeper-3.4.6/bin/../build/lib/*.jar :/usr/share/zookeeper-3.4.6/bin/../lib/slf4j-log4j12-1.6.1.jar :/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.2.16.jar :/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/*.jar : /usr/share/zookeeper-3.4.6/bin /../ conf:
No sistema operacional do Windows, você precisa executar o script zkenv.cmd. Agora você pode usar a variável ClassPath para compilar e executar programas Java escritos usando a API do Zookeeper. O script zkenv.sh pode ser encontrado no arquivo .bashrc do diretório inicial da Uni/Linux para evitar usá -lo sempre que a sessão do shell for iniciada.
O segundo primeiro programa do Zoookeeper
Para introduzir a API Java Zookeeper, vamos começar com um programa muito simples que pode se conectar à instância do Zookeeper no host local e, se a conexão for bem -sucedida, ele imprimirá uma lista de Znodes sob o caminho raiz do espaço para nome do Zookeeper.
O código para este programa é o seguinte:
/*Nosso primeiro programa de Zookeeper*/importar java.io.ioException; importar java.util.arraylist; importar java.util.list; importar org.apache.zookeeper.keeperexception; importar org.apache.zookeeper.zookeeper; public Classe HellooKeeper {public staid. "Localhost: 2181"; string zpath = "/"; list <string> zoOchildren = new ArrayList <String> (); Zookeeper zk = new Zookeeper (Hostport, 2000, null); if (zk! "); para (String Child: ZoOchildren) {// imprima o childrensystem.out.println (filho);}} catch (keeterexception e) {e.printStackTrace ();} catch (interruptedException e) {e.printStacktrace ();}}}}}}}}}}}}}}}}}}}}}}Antes de construir e executar o trecho de código anterior, vamos ver o que ele faz especificamente. O código começa com a instrução de importação. Usando essas instruções, importamos os pacotes exigidos por cada componente do programa. Como mencionado anteriormente, o pacote org.apache.zookeeper contém todas as classes e interfaces exigidas pelo cliente para interagir com o servidor Zookeeper. Depois de importar o pacote, uma classe chamada Hellozookeeper é definida. Como estamos nos conectando à instância do Zookeeper em execução no mesmo sistema, defina o host e a porta como localhost: 2181 no método principal. A linha de código ZK = New Zookeeper (Hostport, 2000, NULL) chama o construtor Zookeeper, que tenta se conectar ao servidor Zookeeper e retorna uma referência. Para programas de clientes que se conectam à instância do Zookeeper Server e mantenham essa conexão, é necessária uma sessão em tempo real. Neste exemplo, a referência retornada pelo objeto ZK instanciado pelo construtor representa a sessão. A API do Zookeeper é construída em torno dessa referência e cada chamada de método requer uma referência para executar.
O construtor da classe Zookeeper usa o código a seguir para criar uma referência à instância do Zookeeper:
Zookeeper (String ConnectString, int sessionTimeout, Watcher Watcher)
Os parâmetros usados são os seguintes:
ConnectString: Host separado por vírgula: Uma lista de números de porta, cada um correspondente a um servidor Zookeeper. Por exemplo, 10.0.0.1:2001, 10.0.0.2:2002 e 10.0.0.3:2003 representam host válido: pares de correspondência de porta para conjuntos Zookeeper de três nós. SessionTimeout: Este é o tempo limite da sessão em milissegundos. Este é o momento em que o Zookeeper não recebeu batimentos cardíacos do cliente antes de anunciar o final da sessão. Vigilante: um objeto Watcher que é notificado se criado quando ocorrem eventos de estado e nó. Esse objeto Watcher precisa ser criado separadamente através de uma classe definida pelo usuário, que implementa a interface do observador e passa o objeto instanciado para o construtor Zookeeper. Os aplicativos do cliente podem receber notificações de vários tipos de eventos, como conexões ausentes, expiração de sessões, etc.
A API Java Zookeeper define um construtor adicional com três parâmetros para especificar operações mais avançadas. O código é o seguinte:
Zookeeper (String ConnectString, int sessionTimeout, Watcher Watcher, Boolean Canbereadnly)
No construtor acima da classe Zookeeper, se definido como true, o parâmetro booleano canbeavonly permite que o cliente criado insira o modo somente leitura no caso de partição de rede. O modo somente leitura é um cenário em que o cliente não consegue encontrar a maioria dos servidores, mas existe um servidor de partição acessível para se conectar a ele no modo somente leitura, que permite solicitações de leitura ao servidor, enquanto as solicitações de gravação não são permitidas. O cliente continua tentando se conectar à maioria dos servidores em segundo plano, permanecendo somente leitura. Um servidor de partição é apenas um subconjunto do grupo Zookeeper, que é formado devido à alocação de rede no cluster. A maioria dos servidores compõe a maioria dos quoros no conjunto.
O construtor a seguir mostra a definição de dois parâmetros adicionais:
Zookeeper (String ConnectString, int sessionTimeout, Watcher Watcher, Long SessionId, Byte [] SessionPasswd)
Este construtor permite que o objeto cliente do Zookeeper crie dois parâmetros adicionais:
SessionID: No caso em que o cliente se reconecta ao servidor Zookeeper, um ID de sessão específico pode ser usado para se referir à sessão sessionPasswd anteriormente conectada: se a sessão especificada exigir uma senha, você pode especificar -a aqui
O construtor a seguir é uma combinação das duas primeiras chamadas:
Zookeeper (String ConnectString, int sessionTimeout, Watcher Watcher, Long SessionId, Byte [] SessionPasswd, Boolean Canbereadonly)
Este construtor é uma combinação das duas primeiras chamadas, permitindo a reconexão à sessão especificada com o modo somente leitura ativado.
Observação
A documentação detalhada da API Java para a classe Zookeeper pode ser consultada em http://zookeeper.apache.org/doc/r3.4.6/api/index.html.
Agora, de volta ao nosso programa Zookeeper. Depois de ligar para o construtor, se a conexão for bem -sucedida, obteremos uma referência ao servidor Zookeeper. Passamos a referência ao método GetChildren através do seguinte código:
zoochildren = zk.getchildren (zpath, false)
O método GetChildren (caminho da string, relógio booleano) da classe Zookeeper retorna a lista de filhos de Znode no caminho fornecido. Apenas iteramos pela lista retornada por esse método e imprimimos a string no console.
Nomeie o programa hellozookeeper.java e compile nosso programa da seguinte forma:
$ javac -cp $ clássy hellozookeeper.java
Antes de executar o programa, precisamos iniciar a instância do Zookeeper Server usando o seguinte comando:
$ $ {Zk_home} /bin/zkserver.sh startExecute o programa da seguinte forma:
$ java -cp $ Classpath hellozookeeper
O executor imprimirá uma mensagem de log no console, exibindo a versão Zookeeper, versão Java, Java ClassPath, Server Architecture etc. Usado. Aqui estão algumas dessas mensagens de log:
As mensagens de log geradas pela API Java Zookeeper são muito úteis para depuração. Ele nos fornece informações sobre o cliente que se conecta ao servidor Zookeeper, estabelecendo uma sessão e outros antecedentes. As três últimas mensagens de log mostradas acima nos dizem como o cliente inicia a conexão usando os parâmetros especificados no programa e como o servidor atribui o ID da sessão ao cliente após uma conexão bem -sucedida.
Finalmente, a execução do programa finalmente gera o seguinte no console:
Podemos usar o Shell Zookeeper para verificar a correção do programa:
$ $ Zk_home/bin/zkcli.sh -server localhost
Parabéns! Nós apenas escrevemos com sucesso nosso primeiro programa de clientes Zookeeper.
Segundo, implemente a interface do observador
O monitoramento de observadores do Zookeeper permite que os clientes recebam notificações de servidores Zookeeper e lidam com esses eventos quando ocorrem. A API Java Zookeeper fornece uma interface pública chamada Watcher que a classe de manipulador de eventos do cliente deve implementar para receber notificações de eventos sobre eventos do servidor Zookeeper. Programaticamente, os aplicativos usando esses clientes lidam com esses eventos registrando objetos de retorno de chamada no cliente.
Implementaremos a interface Watcher para lidar com eventos gerados pelo Zookeeper quando os dados associados ao Znode são alterados.
A interface do observador é declarada da seguinte maneira no pacote org.apache.zookeeper:
Public Interface Watcher {Void Process (Evento WatchedEvent);}Para demonstrar o Znode Data Monitor (Watcher), existem duas classes Java: DataWatcher e DataUpdater. O DataWatcher será executado o tempo todo e ouvirá eventos Nodedatachange do servidor Zookeeper no caminho do znode /myconfig especificado. A classe DataUpdater atualizará periodicamente os campos de dados neste caminho do Znode, que gerará eventos e, ao receber esses eventos, a classe DataWatcher imprimirá os dados alterados para o console.
A seguir, o código da classe DataWatcher.java:
importar java.io.ioException; importar org.apache.zookeeper.createmode; importar org.apache.zookeeper.keeperexception; importar org.apache.zookeeper.watchEDevent; import.apache.zookeeper.watcher; import.ACHEESOMEPER.ZOOKEFEFSEFS; DataWatcher implementa observador, Runnable {private Static String hostport = "localhost: 2181"; String estática privada zoodatapath = "/myConfig"; byte zoo_data [] = null; zookeeper zk; public datawatcher () {Try {zk = new Zookeeper (hostport (2000, 2000, 2000; Znode Se não existe, com o seguinte código: if (zk.exists (Zoodatapath, este) == null) {zk.create (zoodatapath, ". {E.PrintStackTrace ();}}} Catch (ioException e) {e.printStackTrace ();}} public void printData () lança interruptedException, Keeterexception {zoo_data = zk.getData (zoodatapath, this, nul); do znode para o console: system.out.printf ("/ncurrent dados @ zk path %s: %s", zoodatapath, zstring);} @ substituir o processo de void nulo (sigelingEvent Event) {System.out.printf ("/nevent: %s", event.tosTring (); (event.getType () == event.eventType.nodedAtAChanged) {try {printData ();} catch (interruptedException e) {ePrintStackTrace ();} Catch (Keeterexception e) {E.PrintStackTrace ();}} public static é {DataWatcher DataWatcher = new DataWatcher (); DataWatcher.printData (); DataWatcher.run ();} public void run () {try {synchronized (this) {while) {wait ();}}}} catch (interruptedException e) {E.PrintStackTrace (); Thread.CurrentThread (). Interrupt ();}}}Vamos dar uma olhada no código da classe DataWatcher.java para entender a implementação de um monitor do Zookeeper. A classe pública DataWatcher implementa a interface do observador e a interface executável e pretende executar o monitor como um thread. O método principal cria uma instância da classe DataWatcher. No código anterior, o construtor DataWatcher tenta se conectar a uma instância do Zookeeper em execução no host local. Se a conexão for bem -sucedida, usamos o código a seguir para verificar se o caminho do Znode/MyConfig existe:
if (zk.exists (Zoodatapath, this) == null) {Se o znode não existir no espaço para nome do Zookeeper, a chamada de método existe retorna NULL e tente criá -lo como um znode persistente usando o código da seguinte forma:
zk.create (zoodatapath, "" .getbytes (), zoodefs.ids.open_acl_unsafe, cretemode.persistent);
Em seguida, é o método do processo, que é declarado na interface do observador do org.apache.zookeeper e implementado pela classe DataWatcher usando o seguinte código:
Processo Public Void (Evento WatchedEvent) {Por simplicidade, no método do processo, os eventos recebidos da instância do Zookeeper são impressos e apenas eventos do tipo NodedAtachanged são mais processados da seguinte forma:
if (event.getType () == event.eventType.nodedatachanged)
Quando qualquer atualização ou alteração ocorre no campo de dados do caminho do Znode/MyConfig e um evento do tipo NodedAtachanged é recebido, o método PrintData é chamado para imprimir o conteúdo atual do znode. Ao executar uma chamada getData no Znode, definimos um monitor novamente, que é o segundo parâmetro do método, conforme mostrado no código a seguir:
zoo_data = zk.getdata (Zoodatapath, este, nulo);
Os eventos de monitoramento são gatilhos únicos enviados aos clientes que definem o monitoramento. Para receber continuamente adicionais notificações de eventos, os clientes devem redefinir o monitor.
DataUpDater.java é uma classe simples que se conecta à instância do Zookeeper, executando o host local e atualiza o campo de dados do Znode Path/MyConfig com uma string aleatória. Aqui, optamos por atualizar o znode com uma string universal de identificador exclusivo (UUID), porque as chamadas subsequentes do gerador UUID garantirão a geração de seqüências exclusivas.
O código de classe DataUpdater.java é o seguinte:
importar java.io.ioException; importar java.util.uuid; importar org.apache.zookeeper.keeperexception; importar org.apache.zookeeper.watchEdEvent; imported.apache.zookeeper.watcher; importância orgacheement.zookeeper.Zookeper; "LocalHost: 2181"; String estática privada Zoodatapath = "/myConfig"; Zookeeper zk; public DataUpDater () lança IoException {Try {zk = new Zookeeper (Hostport, 2000, this);} Catch (IOException e) {E.PrintStackTrace (); Uuid string.public void run () lança interruptedException, keeterexception {while (true) {string uuid = uuid.randomuuid (). Tostring (); byte zoe_data [] = uuid.getbytes (); zk.setData (zaodataTATATATATATA [] = uuid.getbytes (); zk.setData (zaodataTATATATATATATATATATATATATATATATATATATATATATATATATATATATATA (] // Durma para 5 segundos} Catch (interruptEdException e) {thread.currentThread (). {System.out.printf ("/nevent recebeu: %s", event.toString ());}}O código acima faz com que o servidor Zookeeper acione um evento NodedAtachanged. Como o DataWatcher define o monitoramento deste caminho de znode, ele recebe notificações de eventos de mudança de dados. Em seguida, ele recupera os dados atualizados, redefine o monitoramento e imprime os dados no console.
Use o seguinte comando para compilar as classes DataWatcher e DataUpdater:
$ javac cp $ classe de classe datawatcher.java $ javac cp $ classe de classe dataUpDater.java
Para executar o programa de monitor e atualização, duas janelas do terminal precisam ser abertas. Quero executar o monitor primeiro porque ele cria o znode de /myconfig (se ele não tiver sido criado no espaço para nome do Zookeeper). Antes de executar o monitor, verifique se o servidor Zookeeper está em execução no host local.
Em uma das janelas do terminal, execute a classe Watcher, executando o seguinte comando:
$ java cp $ ClassPath DataWatcher
Emitir uma mensagem semelhante à mostrada na captura de tela a seguir:
Conforme mostrado na captura de tela anterior, o caminho do Znode/MyConfig é criado pela classe DataWatcher. Ele também imprime o conteúdo do Znode, mas não no console, porque não definimos dados ao criar o znode. Quando o Znode é criado, o monitor da classe recebe uma notificação de evento do tipo NodeCreated, que é impresso no console. A classe DataWatcher continua executando e ouve eventos no nó /myconfig do servidor Zookeeper.
Vamos executar a classe DataUpdater em outra janela do terminal:
$ java -CP $ ClassPath DataUpDater
Depois de registrar a mensagem inicial de log específica do Zookeeper no console, a classe DataUpdater é executada sem solicitar. Ele define uma nova sequência UUID no campo de dados do caminho Zookeeper/MyConfig. Então, veja que a cada 5 segundos, a saída exibida na captura de tela abaixo é impressa na janela do terminal que executa o DataWatch:
O DataWatcher também pode ser testado usando o Shell Zookeeper. Continue executando a classe DataWatcher no terminal como antes, e chame o Zookeeper Shell em outro terminal e execute o comando mostrado na captura de tela a seguir:
No terminal em que o DataWatcher está sendo executado, a seguinte mensagem é impressa:
Três exemplos - monitor de cluster
Os serviços populares fornecidos pela Internet, como email, plataformas de serviço de arquivo, jogos on -line etc., são servidos por centenas ou milhares de servidores que estão altamente disponíveis em vários data centers, que geralmente são geograficamente separados. Nesse cluster, alguns nós de servidores dedicados são configurados para monitorar a atividade dos servidores que hospedam serviços ou aplicativos na rede de produção. Em um ambiente de computação em nuvem, esses nós de monitoramento que também são usados para gerenciar o ambiente em nuvem são chamados de controladores em nuvem. Um trabalho importante desses nós do controlador é detectar falhas nos servidores de produção em tempo real e notificar os administradores de acordo e tomar as medidas necessárias, como falhar nos aplicativos no servidor com falha em outro servidor, garantindo tolerância a falhas e alta disponibilidade.
Nesta seção, usaremos a API do cliente Java Zookeeper para desenvolver um modelo minimalista de monitor de cluster distribuído. O uso do conceito efêmero de Znode do Zookeeper para construir esse modelo de monitoramento é bastante simples e elegante, conforme descrito nas etapas a seguir:
Cada servidor de produção executa um cliente Zookeeper como um daemon. Esse processo se conecta ao servidor Zookeeper e cria um znode efêmero com um nome (de preferência seu nome de rede ou nome de host) sob o caminho predefinido do espaço para nome /Zookeeper (como /membros). O nó do controlador de nuvem executa o processo do Zookeeper Monitor, que monitora os caminhos/membros e ouve eventos do tipo Nodechildrenchanged. Esse processo de monitor é executado como um serviço ou daemon e define ou redefine o monitoramento no caminho e implementa sua lógica para chamar os módulos apropriados para tomar as ações necessárias para o monitoramento de eventos. Agora, se o servidor de produção for desligado devido a uma falha de hardware ou a uma falha de software, o processo do cliente Zookeeper será encerrado, fazendo com que a sessão entre o servidor e o serviço Zookeeper seja encerrada. Como as propriedades efêmeras do Znode são únicas, o serviço Zookeeper excluirá automaticamente o znode no caminho/membros sempre que a conexão do cliente estiver fechada. A exclusão de Znode no caminho levanta o evento Nodechildrenchanged, para que o processo de observador no controlador da nuvem seja notificado. Ao chamar o método getChildren no caminho/membros, você pode determinar qual nó do servidor foi fechado. O nó do controlador pode então tomar medidas apropriadas, como executar a lógica de recuperação para reiniciar o serviço com falha em outro servidor. Essa lógica pode ser construída para funcionar em tempo real, garantindo quase zero tempo de inatividade e serviços altamente disponíveis.
Para implementar esse modelo de monitoramento de cluster, desenvolveremos duas classes Java. A classe ClusterMonitor executará continuamente o monitor para monitorar caminhos/membros na árvore Zookeeper. Após o processamento do evento elevado, imprimiremos a lista de znode no console e redefiniremos o monitoramento. Outro clusterclient de classe iniciará a conexão com o servidor Zookeeper e criará um znode efêmero em /membros.
Para simular um cluster com vários nós, iniciamos vários clientes no mesmo computador e criamos um znode efêmero usando o ID do processo do processo do cliente. Ao visualizar a identidade do processo, a classe ClusterMonitor pode determinar qual processo do cliente foi fechado e quais processos ainda estão lá. Em casos práticos, os processos do cliente geralmente criam znode efêmero usando o nome do host do servidor atualmente em execução. Os códigos de origem para essas duas classes são mostrados abaixo.
A classe clustermonitor.java é definida da seguinte forma:
importar java.io.ioException; importar java.util.list; importar org.apache.zookeeper.createmode; importar org.apache.zookeeper.keeperexception; importar org.apache.zookeeper.watchedEvent; import.apache.zookeeper.wather; importação ougkeper.watchedEvent; import.apache.okeeper.werker; org.apache.zookeeper.zookeeper; public classe clustermonitor implementa runnable {private static string associoushiproot = "/membros"; private Watcher Final ConnectionWatcher; Watcher Final Watcher -Watcher privado; {@OverridePublic void Process (Evento WatchedEvent) {if (event.gettype () == watchger.event.eventtype.none && event.getState () == watchger.event.keePerstate.syncConnected) {System.out.PrintF ("/nevent recebeu:"; new watchper () {@OverridePublic void Process (Evento WatchedEvent) {System.out.printf ("/nevent recebeu: %s", event.toString ()); if (event.gettype () == Event.EventType.nodechenChanged) {Try {/obtenha corrente zk.getChildren (associados na parte); parede ("!! Zookeeper (Hostport, 2000, ConnectionWatcher); // Verifique se o znode pai (zk.exists (associados na False) == null) {zk.create (associados, "se setMoMode". = zk.getChildren (associados, Childrenwatcher); system.err.println ("membros:" + filhos);} public sincronizado void close () {try {zk.close ();} catch wall (structException e) {E.PrintStack Splrace ();}} Wall (string) mensagem);} public void run () {try {synchronized (this) {while (alive) {wait ();}}} catch (interruptEdException e) {e.printStacktrace (); thread.currentThread (). InterrompedException, keeterexception {if (args.length! = 1) {System.err.println ("Uso: ClusterMonitor <host: port>"); system.exit (0);} string hostport = args [0]; new ClusterMonitor (hostport) .run ();}}A classe clusterClient.java é definida da seguinte forma:
importar java.io.ioException; importar java.lang.management.ManagementFactory; importar org.apache.zookeeper.createmode; importar org.apache.zookeeper.keeperexception; importoke.apache.zookeeper.watchEvent; import.aMood.ookeper.apachener; org.apache.zookeeper.zookeeper; classe pública clusterclient implementa o observador, runnable {private static string associoushiproot = "/membros"; zookeeper zk; public clusterClient (string hostport, long Pid) {string ProcessId = pid.tostring (); tentativa {zk = newokeeper) {E.PrintStackTrace ();} if (zk! = null) {try {zk.create (associoushiproot + '/' + processId, processId.getBytes (), ids.open_acl_unsafe, CreateMode.ephemeral);} (} (KeepExEcking | InterendException e) { void close () {try {zk.close ();} catch (interruptEdException e) {e.printStackTrace ();}}@SubsteridePublic void Process (WatchEDEDEvent Event) {System.out.printf ("/nevent recebeu: %s", event.tostring ());}; {wait ();}}} catch (interruptEdException e) {e.printStackTrace (); thread.currentThread (). <Host: port> "); System.Exit (0);} String hostport = args [0]; // Obtenha o nome IDstring Nome = ManagementFactory.GetRuntImxBean (). GetName (); int index = Name.Indexof ('@'); ProcessId = Long.Parselong (Name.Substring (0, Index);Use o seguinte comando para compilar essas duas classes:
$ JAVAC -CP $ ClassPath ClusterMonitor.java $ javac -cp $ ClassPath clusterClient.java
Para executar o modelo de monitoramento de cluster, abra dois terminais. Em um dos terminais, execute a classe ClusterMonitor. Em outro terminal, várias instâncias são executadas executando a classe ClusterClient em segundo plano.
No primeiro terminal, execute a classe ClusterMonitor:
$ java -CP $ ClassPath ClusterMonitorLocAlHost: 2181
Conforme mostrado no exemplo anterior, você vê a mensagem de log de depuração da API do cliente. Finalmente, a classe ClusterMonitor começa a monitorar o evento e inserir o seguinte conteúdo:
Agora execute cinco instâncias da classe ClusterClient para simular cinco nós de um cluster. O ClusterClient cria um znode efêmero usando seu próprio ID de processo no caminho dos membros da árvore 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 ClusterClient LocalHost: 211 211 [2] 4045 $ Java -CP $ clusterclient LocalHost: 211 [2] 4045 $ Java e 1 CLUSTRATCLIFE -CP $ ClassPath ClusterClient LocalHost: 2181 2> & 1>/dev/null & [4] 4072 $ java -cp $ ClassPath ClusterClient loclient locient LocalHost: 2181 2> & 1>/dev/null & [5] 4084
Correspondendo a isso, será observado que a classe ClusterMonitor detecta essas novas instâncias de classe ClusterClient, pois está monitorando os eventos no caminho /membros da árvore do Zookeeper. Isso simula um evento de união de nós em um cluster real. A saída pode ser vista no terminal da classe ClusterMonitor, que é semelhante ao mostrado na captura de tela abaixo:
Agora, se um processo clusterClient.java for morto, a sessão que mantém com o servidor Zookeeper será encerrada. Portanto, o znode efêmero criado pelo cliente será excluído. A exclusão desencadeará o evento Nodechildrenchanged, que será capturado pela classe ClusterMonitor. Isso simula um cenário em que um nó sai no cluster.
Vamos encerrar o processo ClusterClient com ID 4084:
$ kill -9 4084
A captura de tela a seguir mostra a saída no terminal da classe ClusterMonitor. Ele lista os processos atualmente disponíveis e seus IDs de processo que imitam o servidor em tempo real:
A implementação de exemplo do modelo de monitoramento de cluster simples e elegante acima demonstra o verdadeiro poder do Zookeeper. Sem o Zookeeper, desenvolver esse modelo que pode monitorar a atividade do nó em tempo real seria uma tarefa verdadeira assustadora.