この例では、Java 3.4.6バージョンを使用しています。この例は、学習した後に理解できない場合に誰もが議論するのに便利です。
アプリケーションを開発するためのZookeeper Javaバインディングは、主に2つのJavaパッケージで構成されています。
org.apache.zookeeper
org.apache.zookeeper.data
org.apache.zookeeperパッケージは、Zookeeperによって監視されているインターフェイス定義とZookeeper用のさまざまなコールバックハンドラーで構成されています。 Zookeeperクライアントクラスライブラリの主要なクラスと、多くのZookeeperイベントの種類と状態の静的な定義を定義します。 org.apache.zookeeper.dataパッケージは、アクセス制御リスト(ACL)、ID、統計など、データレジスタ(Znodesとも呼ばれる)に関連する機能を定義します。
org.apache.zookeeper.server、org.apache.zookeeper.server.quorum and org.apache.zookeeper.server.upgradeパッケージZookeeper Java APIのパッケージは、サーバーの実装の一部です。 org.apache.zookeeper.clientパッケージは、Zookeeperサーバーのステータスを照会するために使用されます。
開発環境に備えます
Apache Zookeeperは複雑なソフトウェアであるため、他の多くのクラスライブラリを実行する必要があります。依存関係ライブラリは、Zookeeper DistributionのJARファイルとしてLIBディレクトリに含まれています。コアZookeeper JARファイル名は、ホームディレクトリにあるZookeeper-3.4.6.jarです。
Java Zookeeperアプリケーションを開発するには、ClassPathをZookeeper JARに設定する必要があります。Zookeeperが依存しているすべてのサードパーティライブラリを設定する必要があります。 BinディレクトリにはZkenv.shファイルがあり、ClassPathを設定するために使用できます。
スクリプトを次のように設定し、コマンドラインで次のステートメントを実行する必要があります。
$ zoobindir = $ {zk_home}/bin $ source $ {zoobindir} /zkenv.shシェル変数ZK_HOMEは、Zookeeperをインストールするパスに設定されています。私の設定では、/usr/share/zookeeperです。その後、ClassPath変数は私のシステムで正しく設定されます。
$ 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.2.16.jar:/usr/share/zookeeper-3.4.6/bin /../ lib/jline-0.9.94.jar:/usr/share/zookeeper-3.4.6/3.6/3.4.6.6.6.6.6/3.4.6.6.6/3.4.6.6/3.4.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6/. :/usr/share/zookeeper-3.4.6/bin/../ src/java/lib/*。jar:/usr/share/zookeeper-3.4.6/bin/../ conf:
Windowsオペレーティングシステムでは、zkenv.cmdスクリプトを実行する必要があります。 ClassPath変数を使用して、Zookeeper APIを使用して書かれたJavaプログラムをコンパイルおよび実行できるようになりました。 zkenv.shスクリプトは、uni/linuxのホームディレクトリの.bashrcファイルに記載されており、シェルセッションが開始されるたびに使用しないようにします。
2番目の最初のZookeeperプログラム
Zookeeper Java APIを導入するには、ローカルホストのZookeeperインスタンスに接続できる非常にシンプルなプログラムから始めましょう。接続が成功した場合、Zookeeper Namespaceのルートパスの下にZnodeのリストを印刷します。
このプログラムのコードは次のとおりです。
/*最初のZookeeperプログラム*/Import java.io.ioexception; Import java.util.arraylist; Import java.util.list; Import org.apache.zookeeper.keeperexception; Import org.apache.zookeeper.zookeeper; public vioid agows [sting intic static vioid agows] hostport = "localhost:2181"; string zpath = "/"; list <string> zoochildren = new arraylist <string>(); zookeeper zk = new zookeeper(hostport、2000、null); if(zk!= null){try {zoochildren = zk.getChildren = zned.path.path. '/': "); for(string child:zoochildren){// childrensystem.out.println(child);}} catch(keeperexception e){e.printstacktrace();} catch(interruptedexception e){e.printstacktrace();}}}}以前のコードスニペットを構築して実行する前に、それが具体的に何をしているか見てみましょう。コードはインポートステートメントから始まります。これらのステートメントを使用して、プログラムの各コンポーネントに必要なパッケージをインポートします。前述のように、org.apache.zookeeperパッケージには、クライアントがZookeeperサーバーと対話するために必要なすべてのクラスとインターフェイスが含まれています。パッケージをインポートした後、hellozookeeperという名前のクラスが定義されます。同じシステムで実行されているZookeeperインスタンスに接続しているため、メインメソッドのホストとポート文字列をLocalHost:2181として定義します。コードZK = New Zookeeper(Hostport、2000、Null)のラインは、Zookeeperコンストラクターを呼び出します。これは、Zookeeperサーバーに接続しようとし、参照を返します。 Zookeeper Serverインスタンスに接続し、その接続を維持するクライアントプログラムの場合、リアルタイムセッションが必要です。この例では、コンストラクターによってインスタンス化されたZKオブジェクトによって返される参照がセッションを表します。 Zookeeper APIはこのリファレンスを中心に構築されており、各メソッド呼び出しでは実行するための参照が必要です。
Zookeeperクラスのコンストラクターは、次のコードを使用して、Zookeeperインスタンスへの参照を作成します。
Zookeeper(String ConnectString、int SessionTimeout、Watcher Watcher)
使用されるパラメーターは次のとおりです。
ConnectString:CommaSeparated Host:それぞれZookeeperサーバーに対応するポート番号のリスト。たとえば、10.0.0.1:2001、10.0.0.2:2002および10.0.0.3:2003は、有効なホストを表しています:3つのノードのZookeeperアンサンブルのポートマッチングペア。 SESSIONTIMEOUT:これは、ミリ秒単位のセッションタイムアウトです。これは、Zookeeperがセッションの終了を発表する前にクライアントから鼓動を取得しなかったときです。ウォッチャー:状態が変更され、ノードイベントが発生したときに作成された場合に通知されるウォッチャーオブジェクト。このウォッチャーオブジェクトは、ユーザー定義のクラスを通じて個別に作成する必要があります。これにより、ウォッチャーインターフェイスを実装し、インスタンス化されたオブジェクトをZookeeperコンストラクターに渡す必要があります。クライアントアプリケーションは、接続の欠落、セッションの有効期限など、さまざまな種類のイベントの通知を受信できます。
Zookeeper Java APIは、より高度な操作を指定する3つのパラメーターを備えた追加のコンストラクターを定義します。コードは次のとおりです。
Zookeeper(String ConnectString、int SessionTimeout、Watcher Watcher、Boolean Canbereadonly)
Zookeeperクラスの上記のコンストラクターでは、Trueに設定されている場合、Boolean CanbereAdonlyパラメーターを使用すると、作成されたクライアントはネットワークパーティションの場合に読み取り専用モードを入力できます。読み取り専用モードは、クライアントがサーバーの大部分を見つけることができないシナリオですが、読み取り専用モードで接続するためのアクセス可能なパーティションサーバーがあります。クライアントは、読み取り専用のままでいる間、バックグラウンドのほとんどのサーバーに接続しようとします。パーティションサーバーは、クラスター内のネットワーク割り当てのために形成されるZookeeperグループのサブセットにすぎません。ほとんどのサーバーは、ほとんどのクォーラムをアンサンブルで構成しています。
次のコンストラクターは、2つの追加パラメーターの定義を示しています。
Zookeeper(String ConnectString、int SessionTimeout、Watcher Watcher、Long SessionId、Byte [] SessionPassWD)
このコンストラクターにより、Zookeeperクライアントオブジェクトは2つの追加パラメーターを作成できます。
SESSIONID:クライアントがZookeeperサーバーに再接続する場合、特定のセッションIDを使用して、以前に接続されたセッションセッションPassWDを参照できます。指定されたセッションにパスワードが必要な場合は、ここで指定できます。
次のコンストラクターは、最初の2つの呼び出しの組み合わせです。
ZooKeeper(String ConnectString、int SessionTimeout、Watcher Watcher、Long SessionId、Byte [] SessionPasswd、Boolean Canbereadonly)
このコンストラクターは、最初の2つの呼び出しの組み合わせであり、読み取り専用モードを有効にして指定されたセッションに再接続できます。
注記
Zookeeperクラスの詳細なJava APIドキュメントは、http://zookeeper.apache.org/doc/r3.4.6/api/index.htmlで質問できます。
さて、Zookeeperプログラムに戻ります。コンストラクターを呼び出した後、接続が成功した場合、Zookeeperサーバーへの参照を取得します。次のコードを使用して、GetChildrenメソッドへの参照を渡します。
ZooChildren = Zk.GetChildren(ZPath、False)
ZookeeperクラスのGetChildren(String Path、Boolean Watch)メソッドは、指定されたパス上のZnodeの子供のリストを返します。この方法で返されたリストを反復し、文字列をコンソールに印刷します。
プログラムにhellozookeeper.javaに名前を付け、次のようにプログラムをコンパイルします。
$ javac -cp $ classpath hellozookeeper.java
プログラムを実行する前に、次のコマンドを使用してZookeeper Serverインスタンスを開始する必要があります。
$ $ {zk_home} /bin/zkserver.sh start次のようにプログラムを実行します:
$ java -cp $ classpath hellozookeeper
執行者は、コンソールにログメッセージを印刷し、Zookeeperバージョン、Javaバージョン、Java ClassPath、サーバーアーキテクチャなどを表示します。これらのログメッセージの一部は次のとおりです。
Zookeeper Java APIによって生成されたログメッセージは、デバッグに非常に役立ちます。 Zookeeperサーバーに接続し、セッションやその他の背景を確立するクライアントに関する情報を提供します。上記の最後の3つのログメッセージは、プログラムで指定されたパラメーターを使用してクライアントが接続を開始する方法と、接続が成功した後にサーバーがセッションIDをクライアントに割り当てる方法を教えてくれます。
最後に、プログラムの実行は最終的にコンソールで以下を出力します。
Zookeeperシェルを使用して、プログラムの正しさを確認できます。
$ $ ZK_HOME/BIN/ZKCLI.SH -SERVER LOCALHOST
おめでとう!最初のZookeeperクライアントプログラムを正常に作成しました。
第二に、ウォッチャーインターフェイスを実装します
Zookeeper Watcher監視により、クライアントはZookeeperサーバーから通知を受け取り、発生したときにこれらのイベントを処理できます。 Zookeeper Java APIは、Zookeeper Serverからイベントに関するイベント通知を受信するためにクライアントイベントハンドラークラスが実装する必要があるというWatcherと呼ばれるパブリックインターフェイスを提供します。プログラムでは、このようなクライアントを使用するアプリケーションは、クライアントにコールバックオブジェクトを登録することにより、これらのイベントを処理します。
Znodeに関連付けられたデータが変更されたときに、Zookeeperによって生成されたイベントを処理するWatcherインターフェイスを実装します。
ウォッチャーインターフェイスは、org.apache.zookeeperパッケージで次のように宣言されています。
パブリックインターフェイスウォッチャー{void Process(watchedevent event);}Znode Data Monitor(Watcher)を実証するには、DataWatcherとDataUpDaterの2つのJavaクラスがあります。 DataWatcherは常に実行され、 /myConfig指定されたZnodeパスでZookeeperサーバーからNodedatachangeイベントを聴きます。 DataUpDaterクラスは、このZnodeパスのデータフィールドを定期的に更新し、イベントを生成し、これらのイベントを受信すると、DataWatcherクラスは変更されたデータをコンソールに印刷します。
以下は、datawatcher.javaクラスのコードです。
java.io.ioexception; Import org.apache.zookeeper.createmode; Import org.apache.zookeeper.keeperexception; Import org.apache.zookeeper.watchedevent; Import org.apache.zookeeper.watcher; import org.apache.zookeeper.zoodefs; apache.zookeeper.zookeeper; public class datawatcherはウォッチャー、runnable {private static string hostport = "localhost:2181"; private static string zoodatapath = "/myconfig"; byte zoo_data [] = null; zookeeper zk; public datawater 2000、this); if(zk!= null){try {// Znodeが存在しない場合はznodeを作成します。zk.exists(zoodatapath、this)== null){zk.create(zoodatapath、 "" .getbytes()、zoodemodee、createmadee、ferteemsistediste。 (kemperexception | arturnexexception e){e.printstacktrace();}}} catch(ioexception e){e.printstacktrace();}} public void printdata()interruptedexception、keeperexception {zoo_data = zk.getdata(zoodatapath、null); string(zoo_data); //次のコードは、znodeの現在のコンテンツをコンソールに印刷します:system.out.printf( "/ncurrent data @ zk path%s:%s"、zoodatapath、zstring);} event.toString()); //タイプnodedatachangedif(event.getType()== event.EventType.NodedAtachanged)のイベントのみを処理します{printData();} catch(interruptedexception e){e.printstacktrace(); static void main(string [] args)throws arturnedexception、kemperexception {datawatcher datawatcher = new datawatcher(); datawatcher.printdata(); datawatcher.run();} public void run(){try {synchronized(this){while){wait() {e.printstacktrace(); shood.currentthread()。arturn();}}}}Zookeeperモニターの実装を理解するために、DataWatcher.javaクラスのコードを見てみましょう。 DataWatcherのパブリッククラスは、ウォッチャーインターフェイスと実行可能なインターフェイスを実装し、モニターをスレッドとして実行するつもりです。主な方法は、DataWatcherクラスのインスタンスを作成します。前のコードでは、DataWatcherコンストラクターは、LocalHostで実行されているZookeeperインスタンスに接続しようとします。接続が成功した場合、次のコードを使用して、Znode Path/MyConfigが存在するかどうかを確認します。
if(zk.exists(zoodatapath、this)== null){ZnodeがZookeeper Namespaceに存在しない場合、Exists Method CallはNULLを返し、次のようにコードを使用して永続的なZnodeとして作成しようとします。
zk.create(zoodatapath、 "" .getBytes()、zoodefs.ids.open_acl_unsafe、createmode.persistent);
次は、org.apache.zookeeperのウォッチャーインターフェイスで宣言され、次のコードを使用してDataWatcherクラスによって実装されているプロセスメソッドです。
public void Process(watchedeventイベント){簡単にするために、プロセス方法では、Zookeeperインスタンスから受け取ったイベントが印刷され、nodedatachangedタイプのイベントのみが次のようにさらに処理されます。
if(event.getType()== event.EventType.NodedAtachanged)
Znode Path/myConfigのデータフィールドとnodedatachangedタイプのイベントで更新または変更が発生すると、printDataメソッドがZnodeの現在のコンテンツを印刷するために呼び出されます。 ZnodeでgetData呼び出しを実行すると、次のコードに示すように、メソッドの2番目のパラメーターであるモニターを再度設定します。
zoo_data = zk.getdata(zoodatapath、this、null);
監視イベントは、監視を設定するクライアントに送信される1回限りのトリガーです。さらにイベント通知を継続的に受信するには、クライアントがモニターをリセットする必要があります。
dataupdater.javaは、localhostを実行しているZookeeperインスタンスに接続するシンプルなクラスで、Znode Path/MyConfigのデータフィールドをランダムな文字列で更新します。ここでは、その後のUUIDジェネレーター呼び出しが一意の文字列の生成を保証するため、ユニバーサルユニークな識別子(UUID)文字列でZnodeを更新することを選択します。
dataupdater.javaクラスコードは次のとおりです。
java.io.ioexception; Import java.util.uuid; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.zookeeper.zookeeper.zookeeper.watcher; import org.apache.zookeeper.zookeeper.zookeeper.zookeeper.zookeeper.zookeeper.zookeeper.zookeeper.zookeeper "localhost:2181"; private static string zoodatapath = "/myconfig"; zookeeper zk; public dataupdater()throws ioexception {try {zk = new zookeeper(hostport、2000、this);} catch(ioexception e){excception exceptrace {e.printstrace();新しいuuid string.public void run()throws arturnedexception、kemperexception {while){string uuid = uuid.randomuuid()。toString(); byte zoo_data [] = uuid.getbytes(); zk.setdata(zooodatapath swood.1); // 5秒間スリープ} catch(arturnedexception e){thread.currentthread()。 {system.out.printf( "/nevent received:%s"、event.tostring();}}}上記のコードにより、ZookeeperサーバーはNodedatachangedイベントをトリガーします。 DataWatcherはこのZnodeパスの監視を設定するため、データ変更イベントの通知を受信します。次に、更新されたデータを取得し、監視をリセットし、コンソール上のデータを印刷します。
次のコマンドを使用して、DataWatcherとDataUpDaterクラスをコンパイルします。
$ javac cp $ classpath datawatcher.java $ javac cp $ classpath dataupdater.java
モニターと更新プログラムを実行するには、2つの端末ウィンドウを開く必要があります。 /myconfigのZnodeを作成するため、モニターを最初に実行したい(Zookeeperネームスペースで作成されていない場合)。モニターを実行する前に、Zookeeperサーバーがローカルホストで実行されていることを確認してください。
ターミナルウィンドウの1つで、次のコマンドを実行してWatcherクラスを実行します。
$ java cp $ classpath datawatcher
次のスクリーンショットに示されているものと同様のメッセージを出力します。
前のスクリーンショットに示されているように、Znode Path/MyConfigはDataWatcherクラスによって作成されます。また、ZnodeではなくZnodeの内容を印刷します。これは、Znodeの作成時にデータを設定しないためです。 Znodeが作成されると、クラスのモニターは、コンソールに印刷された型NodeCreatedのイベント通知を受け取ります。 DataWatcherクラスは、Zookeeperサーバーの /myConfigノードのイベントを実行し続け、聴いています。
別の端末ウィンドウでDataUpDaterクラスを実行しましょう。
$ java -cp $ classpath dataupdater
最初のZookeeper固有のログメッセージをコンソールにログに記録した後、DataUpDaterクラスはプロンプトなしで実行されます。 Zookeeper Path/MyConfigのデータフィールドに新しいUUID文字列を設定します。したがって、5秒ごとに、以下のスクリーンショットに表示されている出力がターミナルウィンドウを実行しているターミナルウィンドウに印刷されていることを確認してください。
DataWatcherは、Zookeeperシェルを使用してテストすることもできます。以前のようにターミナルでDataWatcherクラスを実行し続け、別の端末でZookeeperシェルを呼び出し、次のスクリーンショットに示すコマンドを実行します。
DataWatcherが実行されている端末では、次のメッセージが印刷されています。
3つの例 - クラスターモニター
電子メール、ファイルサービスプラットフォーム、オンラインゲームなど、インターネットを介して提供される人気のあるサービスは、多くの場合、地理的に分離されている複数のデータセンターで非常に利用できる数百または数千のサーバーが提供しています。このようなクラスターでは、いくつかの専用サーバーノードがセットアップされており、生産ネットワークでサービスまたはアプリケーションをホストするサーバーのアクティビティを監視します。クラウドコンピューティング環境では、クラウド環境の管理にも使用されるこのような監視ノードは、クラウドコントローラーと呼ばれます。これらのコントローラーノードの重要な仕事は、生産サーバーの障害をリアルタイムで検出し、それに応じて管理者に通知し、障害のあるサーバー上のアプリケーションを介して障害を介して障害の許容度と高可用性を確保するなどの必要な測定を行うことです。
このセクションでは、Zookeeper JavaクライアントAPIを使用して、ミニマリスト分散クラスターモニターモデルを開発します。次の手順で説明されているように、ZookeeperのはかないZnodeコンセプトを使用してこの監視モデルを構築することは非常にシンプルでエレガントです。
各生産サーバーは、Zookeeperクライアントをデーモンとして実行します。このプロセスは、Zookeeperサーバーに接続し、 /Zookeeperネームスペース( /メンバーなど)の事前定義されたパスの下に名前(できればネットワーク名またはホスト名)を持つはかないZnodeを作成します。クラウドコントローラーノードは、Zookeeperモニタープロセスを実行します。このプロセスは、パス/メンバーを監視し、nodeChildrencangedのタイプのイベントを聴きます。このモニタープロセスは、サービスまたはデーモンとして実行され、パス上の監視を設定またはリセットし、イベントを監視するために必要なアクションを実行するために適切なモジュールを呼び出すためのロジックを実装します。これで、ハードウェアの障害またはソフトウェアのクラッシュにより生産サーバーがシャットダウンされた場合、Zookeeperクライアントプロセスが終了し、サーバーとZookeeperサービスの間のセッションが終了します。一時的なZnodeのプロパティは一意であるため、Zookeeperサービスは、クライアント接続が閉じるたびにパス/メンバーのZnodeを自動的に削除します。パスでのZnodeの削除は、nodeChildlanchangedイベントを提起するため、クラウドコントローラーのオブザーバープロセスに通知されます。パス/メンバーのgetChildrenメソッドを呼び出すことにより、どのサーバーノードが閉じられているかを判断できます。コントローラーノードは、リカバリロジックを実行して別のサーバーで失敗したサービスを再起動するなど、適切な測定を行うことができます。このロジックは、リアルタイムで動作するように構築することができ、ゼロのダウンタイムと非常に利用可能なサービスを保証することができます。
このクラスター監視モデルを実装するために、2つのJavaクラスを開発します。 ClusterMonitorクラスは、Zookeeperツリーのパス/メンバーを監視するためにモニターを継続的に実行します。上昇したイベントを処理した後、コンソールにZnodeリストを印刷し、監視をリセットします。別のクラスClusterClientは、Zookeeperサーバーへの接続を開始し、 /メンバーの下ではかなかZnodeを作成します。
複数のノードを持つクラスターをシミュレートするために、同じコンピューターで複数のクライアントを開始し、クライアントプロセスのプロセスIDを使用してはかないZnodeを作成します。プロセスIDを表示することにより、ClusterMonitorクラスは、どのクライアントプロセスが閉じられており、どのプロセスがまだあるかを決定できます。実際の場合、クライアントプロセスは通常、現在実行中のサーバーのホスト名を使用して一時的なZnodeを作成します。これら2つのクラスのソースコードを以下に示します。
clusterMonitor.javaクラスは次のように定義されています。
java.io.ioexception; Import java.util.list; import org.apache.zookeeper.createmode; import org.apache.zookeeper.keeperexception; import org.zookeeper.watchedevent; import org.apacheeper.watcher.zoeper.zo.zoeper.zo.zoeper.zoeper.zoeper.zoeper.zoeper.zoeeper.zoeeper.zoeeper.watcheeper.watcheper.zookeeper. org.apache.zookeeper.zookeeper; public clustermonitor explmestion runnable {private static string membershiproot = "/members"; private final watcher connectionwatcher; private final watcher childrenwatcher; private zookeeper zk; boolean live = true; public clustermonitor(String connectionsection、connectionecticteception、fatedexectiptection、fatedexectiptectiper) {@OverridePublic void Process(watchedEvent event){if(event.getType()== watcher.event.eventtype.none && event.getState()== watcher.event.keeperstate.syncConnected){system.out.printf( "/nevent:nevent:nevent: watcher(){@overridepublic void process(watchedevent event){system.out.printf( "/nevent receed:%s"、event.tostring())); Zk.getChildren(Memberhiproot、this); wall( "!!クラスターメンバーシップの変更!!!"); wall( "メンバー:" +子供);} catch(keeperexception e){throw new runtimeexception(e);} catch(interruptedexception e){thread.currentthread()。 Zookeeper(Hostport、2000、ConnectionWatcher); //親Znodeが存在することを確認する(zk.exists(memberhiproot、false)== null){zk.create( "clustermonitorroot"。 Znodelist <String> Children = Zk.getChildren(Memberhiproot、Childrenwatcher); System.err.println( "Member:" + Children);} public synchronized void close(){try {zk.close();} catch(interruptedexception e){e.printstrace();}}}} public void wall( {system.out.printf( "/nmessage:%s"、message);} public void run(){try {synchronized(this){while(live){wait();}}} catch(interruptedexception e){e.printstacktrace(); swers.current(); main(string [] args)throws ioexception、arturnedexception、keeperexception {if(args.length!= 1){system.err.err.println( "usage:clustermonitor <host:port>");} string hostport = args [0]; new clustermonitor(host);clusterclient.javaクラスは次のように定義されています。
java.io.ioexception; Import java.lang.management.managementfactory; Import org.apache.zookeeper.createmode; import org.apache.zookeeper.keeperexception; Import org.apache.zookeeper.watchedevent; Import org.apache.zookeeper; import; org.apache.zookeeper.zoodefs.ids; import org.apache.zookeeper.zookeeper; public class clusterclientはウォッチャー、runnable {private static string membershiproot = "/members"; zookeeper zk; public clusterclient(string hostport、long pid) Zookeeper(Hostport、2000、This);} catch(IoException e){e.printstacktrace();} if(zk!= null){try {zk.create + '/' + processid、processid.getbytes()、idopen_acl_acl_unssafe、createmode.eperemeral); e){e.printstacktrace();}}} public synchronized void close(){try {zk.close();} catch(arturnedexception e){e.printStackTrace();}} event.toString());} public void run(){try {synchronized(this){while){wait();}}} catch(arturtedexception e){e.printstacktrace(); thread.currentthread()。 (args.length!= 1){system.err.println( "usage:clusterclient <host:port>"); system.exit(0);} string hostport = args [0]; // managementfactory.getruntimemxbean()。 long.parselong(name.substring(0、index)); new ClusterClient(hostport、processId).run();}}}次のコマンドを使用して、これら2つのクラスをコンパイルします。
$ javac -cp $ classpath clustermonitor.java $ javac -cp $ classpath clusterclient.java
クラスター監視モデルを実行するには、2つの端子を開きます。端末の1つで、ClusterMonitorクラスを実行します。別の端末では、バックグラウンドでClusterClientクラスを実行することにより、複数のインスタンスが実行されます。
最初の端末では、ClusterMonitorクラスを実行します。
$ java -cp $ classpath clustermonitorlocalhost:2181
前の例に示すように、クライアントAPIからのデバッグログメッセージが表示されます。最後に、ClusterMonitorクラスはイベントの監視を開始し、次のコンテンツを入力します。
ClusterClientクラスの5つのインスタンスを実行して、クラスターの5つのノードをシミュレートします。 clusterClientは、Zookeeperツリーの /メンバーパスで独自のプロセスIDを使用してはかないZnodeを作成します。
$ java -cp $ classpath clusterclient localhost:2181 2>&1>/dev/null&[1] 4028 $ java -cp $ clusterclient localhost:2181 2>&1>/dev/null&[2] 4045 $ java -cp $ clusterhostクラスターclusterhost:2181 2&1> dev/1> -cp $ classpath clusterclient localhost:2181 2>&1>/dev/null&[4] 4072 $ java -cp $ classpath clusterclient localhost:2181 2>&1>/dev/null&[5] 4084
これに対応して、ClusterMonitorクラスは、Zookeeperツリーの /メンバーパスでのイベントを監視しているため、これらの新しいClusterClientクラスインスタンスを検出することが観察されます。これにより、実際のクラスターでノード接合イベントがシミュレートされます。出力は、以下のスクリーンショットに示されているものに似ているクラスターマントールクラスの端末に表示できます。
これで、ClusterClient.javaプロセスが殺された場合、Zookeeperサーバーで維持されるセッションが終了します。したがって、クライアントによって作成されたはかないZnodeが削除されます。削除は、ClusterMonitorクラスによってキャプチャされるNodeChildlanchangedイベントをトリガーします。これは、ノードがクラスターに残るシナリオをシミュレートします。
ID 4084でClusterClientプロセスを終了しましょう。
$ kill -9 4084
次のスクリーンショットは、ClusterMonitorクラスの端末の出力を示しています。現在利用可能なプロセスと、リアルタイムサーバーをエミュレートするプロセスIDをリストします。
上記のシンプルでエレガントなクラスター監視モデルの実装の例は、Zookeeperの真の力を示しています。 Zookeeperがなければ、ノードアクティビティをリアルタイムで監視できるモデルを開発することは、本当に困難な作業です。