نستخدم إصدار Java 3.4.6 في هذا المثال. المثال مناسب للجميع لمناقشة ما إذا كنت لا تفهم بعد تعلمه.
يتكون ملزمة Java Zookeeper لتطوير التطبيقات بشكل أساسي من حزمتين Java:
org.apache.zookeeper
org.apache.zookeeper.data
تتكون حزمة org.apache.zookeeper من تعريف الواجهة الذي تتم مراقبته بواسطة ZookeEper ومختلف معالجات رد الاتصال لـ ZookeEper. إنه يحدد الفئات الرئيسية لمكتبة فئة عميل Zookeeper بالإضافة إلى تعريفات ثابتة للعديد من أنواع الأحداث والولايات. تحدد حزمة org.apache.zookeeper.data الميزات المتعلقة بسجلات البيانات (المعروفة أيضًا باسم Znodes) ، مثل قوائم التحكم في الوصول (ACLs) ، IDS ، الإحصائيات ، إلخ.
org.apache.zookeeper.server ، org.apache.zookeeper.server.quorum و org.apache.zookeeper.server.upgrade حزم في Zookeeper Java API هي جزء من تنفيذ الخادم. يتم استخدام حزمة org.apache.zookeeper.client للاستعلام عن حالة خادم zookeeper.
الاستعداد لبيئة التنمية
Apache Zookeeper هو برنامج معقد ، لذلك يتطلب تشغيل العديد من مكتبات الفصول الدراسية الأخرى. يتم تضمين مكتبة التبعية في دليل LIB كملف جرة في توزيع Zookeeper. اسم ملف Zookeeper Jar Core هو Zookeeper-3.4.6.jar ، الموجود في الدليل المنزلي.
لتطوير تطبيق Java Zookeeper ، يجب علينا تعيين ClassPath على جرة Zookeeper ، وجميع مكتبات الطرف الثالث تعتمد عليها ZookeEper. يوجد ملف Zkenv.sh في دليل Bin ، والذي يمكن استخدامه لضبط ClassPath.
نحتاج إلى تعيين البرنامج النصي على النحو التالي وتنفيذ العبارة التالية في سطر الأوامر:
$ Zoobindir = $ {zk_home}/bin $ المصدر $ {zoobindir} /zkenv.shيتم تعيين ZK_Home المتغير shell على المسار لتثبيت 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/zookeper-3.4.6/bin /... : /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 /../ : /usr/share/zookeeper-3.4.6/bin /../ conf:
في نظام تشغيل Windows ، تحتاج إلى تشغيل البرنامج النصي Zkenv.cmd. يمكنك الآن استخدام متغير ClassPath لتجميع وتشغيل برامج Java المكتوبة باستخدام API Zookeeper. يمكن العثور على البرنامج النصي Zkenv.sh في ملف .bashrc للدليل المنزلي في UNI/Linux لتجنب استخدامه في كل مرة يتم فيها بدء جلسة shell.
أول برنامج Zookeeper
لتقديم API Java API Zookeeper ، لنبدأ ببرنامج بسيط للغاية يمكنه الاتصال بمثيل Zookeeper في LocalHost ، وإذا كان الاتصال ناجحًا ، فسيقوم بطباعة قائمة من Znodes تحت مسار الجذر لمساحة اسم Zookeeper.
رمز هذا البرنامج كما يلي:
/. "LocalHost: 2181" ؛ String zPath = "/" ؛ قائمة <Tring> zoochildren = new ArrayList <String> () ؛ zookeeper zk = new Zookeeper (hostport ، 2000 ، null) ؛ if (zk! = null) {try {zochildren = zk.getchildren (zpath ، false) ؛ ") ؛ for (string child: zoochildren) {// print the childrensystem.out.println (child) ؛}} catch (keeperexception e) {e.printstacktrace () ؛قبل بناء وتنفيذ مقتطف الكود السابق ، دعونا نرى ما يفعله على وجه التحديد. يبدأ الرمز ببيان الاستيراد. باستخدام هذه العبارات ، نستورد الحزم التي يتطلبها كل مكون من مكونات البرنامج. كما ذكرنا سابقًا ، تحتوي حزمة org.apache.zookeeper على جميع الفئات والواجهات المطلوبة من قبل العميل للتفاعل مع خادم zookeeper. بعد استيراد الحزمة ، يتم تعريف فصل يدعى HellozOokeeper. نظرًا لأننا نتواصل مع مثيل Zookeeper الذي يعمل في نفس النظام ، حدد سلاسل المضيف والمنافذ على أنها LocalHost: 2181 في الطريقة الرئيسية. يدعو سطر الكود ZK = New Zookeeper (Hostport ، 2000 ، Null) إلى مُنشئ Zookeeper ، الذي يحاول الاتصال بخادم zookeeper وإرجاع مرجع. بالنسبة لبرامج العميل التي تتصل بمثيل خادم ZookeEper والحفاظ على هذا الاتصال ، يلزم وجود جلسة في الوقت الفعلي. في هذا المثال ، يمثل المرجع الذي تم إرجاعه بواسطة كائن ZK الذي تم إنشاءه بواسطة المُنشئ الجلسة. تم تصميم واجهة برمجة تطبيقات Zookeeper حول هذا المرجع ، وتتطلب كل طريقة استدعاء مرجعًا للتنفيذ.
يستخدم مُنشئ فئة ZookeEper الكود التالي لإنشاء مرجع إلى مثيل Zookeeper:
ZookeEper (سلسلة ConnectString ، int sessiontimeout ، مراقب المراقب)
المعلمات المستخدمة على النحو التالي:
ConnectString: مضيف مفصل للفاصلة: قائمة بأرقام المنافذ ، كل منهما يتوافق مع خادم zookeeper. على سبيل المثال ، 10.0.0.1:2001 ، 10.0.0.2:2002 و 10.0.0.3:2003 تمثل مضيفًا صالحًا: أزواج مطابقة للمنفذ لمجموعات Zookeeper من ثلاث عقد. SessionTimeout: هذه هي مهلة الجلسة بالميلي ثانية. هذا هو الوقت الذي لم يحصل فيه Zookeeper على نبضات من العميل قبل الإعلان عن نهاية الجلسة. مراقب: كائن مراقب يتم إخطاره إذا تم إنشاؤه عند تغيير الحالة وتحدث أحداث العقدة. يجب إنشاء كائن المراقب هذا بشكل منفصل من خلال فئة محددة من قبل المستخدم ، والتي تنفذ واجهة المراقب ويمرر الكائن الذي تم إنشاءه إلى مُنشئ Zookeeper. يمكن أن تتلقى تطبيقات العميل إخطارات لأنواع مختلفة من الأحداث ، مثل الاتصالات المفقودة ، وانتهاء من الجلسات ، إلخ.
يحدد Qookeeper Java API مُنشئًا إضافيًا به ثلاث معلمات لتحديد عمليات أكثر تقدمًا. الرمز كما يلي:
Zookeeper (String ConnectString ، Int SessionTimeout ، مراقب المراقب ، Boolean Canbereadonly)
في المُنشئ أعلاه لفئة Zookeeper ، إذا تم ضبطها على TRUE ، فإن المعلمة Boolean Canbereadonly تسمح للعميل الذي تم إنشاؤه بإدخال وضع القراءة فقط في حالة قسم الشبكة. وضع القراءة فقط هو سيناريو حيث لا يمكن للعميل العثور على أي أغلبية من الخوادم ، ولكن هناك خادم قسم يمكن الوصول إليه للاتصال به في وضع القراءة فقط ، والذي يتيح طلبات القراءة للخادم ، بينما لا يُسمح بطلبات الكتابة. يستمر العميل في محاولة الاتصال بمعظم الخوادم في الخلفية بينما لا يزال يبقى القراءة فقط. خادم التقسيم هو مجرد مجموعة فرعية من مجموعة Zookeeper ، والتي تم تشكيلها بسبب تخصيص الشبكة في الكتلة. تشكل معظم الخوادم معظم النصاب في الفرقة.
يعرض المنشئ التالي تعريف معلمتين إضافيتين:
Zookeeper (String ConnectString ، int sessiontimeout ، مراقب مراقب ، Long SessionId ، Byte [] SessionPasswd)
يسمح هذا المُنشئ لكائن عميل ZookeEper بإنشاء معلمتين إضافيتين:
SessionId: في الحالة التي يقوم فيها العميل بإعادة توصيل خادم ZookeEper ، يمكن استخدام معرف جلسة محدد للإشارة إلى الجلسة المتصلة مسبقًا: إذا كانت الجلسة المحددة تتطلب كلمة مرور ، فيمكنك تحديدها هنا
المُنشئ التالي هو مزيج من أول مكالمتين:
Zookeeper (String ConnectString ، int SessionTimeout ، مراقب مراقب ، Long SessionId ، Byte [] SessionPasswd ، Boolean Canbereadonly)
هذا المنشئ هو مزيج من أول مكالمتين ، مما يسمح بإعادة الاتصال بالجلسة المحددة مع تمكين وضع القراءة فقط.
ملحوظة
يمكن الاستعلام عن وثائق Java API المفصلة لفئة Zookeeper على http://zookeeper.apache.org/doc/r3.4.6/api/index.html.
الآن ، العودة إلى برنامج Zookeeper الخاص بنا. بعد استدعاء المُنشئ ، إذا كان الاتصال ناجحًا ، فسوف نحصل على إشارة إلى خادم Zookeeper. نمرر الإشارة إلى طريقة GetChildren من خلال الكود التالي:
حديقة الحيوان = ZK.GetChildren (ZPATH ، FALSE)
تعيد طريقة GetChildren (مسار السلسلة ، الساعة المنطقية) لفئة ZookeEper قائمة أطفال Znode على المسار المحدد. نحن نتكرر فقط على القائمة التي تم إرجاعها بهذه الطريقة وطباعة السلسلة إلى وحدة التحكم.
قم بتسمية البرنامج hellozookeeper.java وتجميع برنامجنا على النحو التالي:
$ javac -cp $ classpath hellozookeeper.java
قبل تشغيل البرنامج ، نحتاج إلى بدء مثيل خادم ZookeEper باستخدام الأمر التالي:
$ $ {zk_home} /bin/zkserver.sh startقم بتشغيل البرنامج على النحو التالي:
$ java -cp $ classpath hellozookeeper
سيقوم المنفذ بطباعة رسالة سجل على وحدة التحكم ، مع عرض إصدار ZookeEper ، إصدار Java ، Java ClassPath ، بنية الخادم ، إلخ. فيما يلي بعض رسائل السجل هذه:
رسائل السجل التي تم إنشاؤها بواسطة java API Zookeeper Java مفيدة للغاية لتصحيح الأخطاء. يوفر لنا معلومات حول العميل الذي يتصل بخادم ZookeEper ، وإنشاء جلسة وخلفية أخرى. تخبرنا رسائل السجل الثلاثة الأخيرة الموضحة أعلاه كيف يبدأ العميل في الاتصال باستخدام المعلمات المحددة في البرنامج ، وكيف يقوم الخادم بتعيين معرف الجلسة للعميل بعد اتصال ناجح.
أخيرًا ، يقوم تنفيذ البرنامج أخيرًا بإخراج ما يلي في وحدة التحكم:
يمكننا استخدام قذيفة Zookeeper للتحقق من صحة البرنامج:
$ $ ZK_HOME/BIN/ZKCLI.SH -Server LocalHost
مبروك! لقد كتبنا فقط أول برنامج عميل ZookeEper لدينا.
ثانياً ، قم بتنفيذ واجهة المراقب
تمكن مراقبة مراقبة Zookeeper العملاء من تلقي إشعارات من خوادم Zookeeper والتعامل مع هذه الأحداث عند حدوثها. يوفر API Java API Zookeeper واجهة عامة تسمى Watcher التي يجب أن تنفذ فئة معالج الأحداث العميل لتلقي إشعارات الأحداث حول الأحداث من خادم ZookeEper. برمجيا ، تعامل التطبيقات التي تستخدم هؤلاء العملاء مع هذه الأحداث عن طريق تسجيل كائنات رد الاتصال مع العميل.
سنقوم بتنفيذ واجهة المراقب للتعامل مع الأحداث التي تم إنشاؤها بواسطة ZookeEper عند تغيير البيانات المرتبطة بـ Znode.
يتم الإعلان عن واجهة المراقب على النحو التالي في حزمة org.apache.zookeeper:
مراقب الواجهة العامة {void عملية (حدث WatchEdevent) ؛}لإظهار مراقبة بيانات Znode (Watcher) ، هناك فئتان Java: DataWatcher و DataUpdater. سيتم تشغيل DataWatcher طوال الوقت والاستماع إلى أحداث novedatachange من خادم Zookeeper في مسار Znode المحدد /myConfig. ستقوم فئة 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 ؛ isport org.zookeeper.zoodefs ؛ org.apache.zookeeper.zOokeeper ؛ فئة عامة datawatcher تنفذ مراقب ، Runnable {private Static String assport = "localhost: 2181" ؛ سلسلة ثابتة Zoodatapath = "/myConfig" ؛ byte zoo_data []] 2000 ، هذا) ؛ if (zk! = null) {try {// إنشاء znode إذا لم يكن موجودًا ، مع الكود التالي: if (zk.exists (zoodatapath ، this) == null) {zk.create (zoodatapath ، ".". |. يطبع الكود التالي المحتوى الحالي لـ Znode إلى وحدة التحكم: system.out.printf ("/ncurrent data @ zk path ٪ s: ٪ s" ، zoodatapath ، zString) ؛} @ overridepublic void. (event.gettype () == event.eventtype.nodedatachanged) {try {printData () ؛ {datawatcher datawatcher = new datawatcher () ؛ datawatcher.printData () ؛ datawatcher.run () ؛} public void run () {try {synchronized (this) {بينما (true) {wait () ؛}}} catch (interruptedException e) {دعنا نلقي نظرة على رمز فئة datawatcher.java لفهم تنفيذ جهاز شاشة Zookokeeper. تقوم فئة DataWatcher العامة بتنفيذ واجهة المراقب والواجهة القابلة للتشغيل ، وتعتزم تشغيل الشاشة كخيط. تنشئ الطريقة الرئيسية مثيلًا لفئة DataWatcher. في الكود السابق ، يحاول مُنشئ DataWatcher الاتصال بمثال zookeeper الذي يعمل على مضيف محلي. إذا نجح الاتصال ، نستخدم الكود التالي للتحقق مما إذا كان Znode Path/MyConfig موجود:
if (zk.exists (zoodatapath ، هذا) == فارغ) {إذا لم يكن Znode موجودًا في مساحة اسم Zookeeper ، فإن طريقة استدعاء الأسلوب الموجودة في إرجاع NULL ومحاولة إنشائها كوحدة Znode مستمرة باستخدام الرمز كما يلي:
ZK.Create (Zoodatapath ، "" .getBytes () ، zoodefs.ids.open_acl_unsafe ، createMode.persistent) ؛
التالي هو طريقة العملية ، التي تم إعلانها في واجهة مراقب Org.apache.zookeeper وتنفيذها بواسطة فئة DataWatcher باستخدام الرمز التالي:
عملية الفراغ العام (حدث WatchedEvent) {من أجل البساطة ، في طريقة العملية ، تتم طباعة الأحداث المستلمة من مثيل Zookeeper ، وتتم معالجة الأحداث الوحيدة من النوع nodedatachanged على النحو التالي:
if (event.gettype () == event.eventtype.nodedatachanged)
عندما يحدث أي تحديث أو تغيير في حقل البيانات الخاص بمسار Znode/MyConfig وحدث من النوع يتم استلام nevedatachanged ، يتم استدعاء طريقة printData لطباعة المحتوى الحالي من Znode. عند تنفيذ مكالمة getData على Znode ، قمنا بتعيين شاشة مرة أخرى ، وهي المعلمة الثانية للطريقة ، كما هو موضح في الكود التالي:
zoo_data = zk.getData (zoodatapath ، هذا ، null) ؛
أحداث المراقبة هي مشغلات لمرة واحدة يتم إرسالها للعملاء الذين يضعون المراقبة. من أجل تلقي مزيد من إشعارات الأحداث بشكل مستمر ، يجب على العملاء إعادة ضبط الشاشة.
DataUpdater.java هي فئة بسيطة تتصل بمثيل Zookeeper الذي يقوم بتشغيل المضيف المحلي ويقوم بتحديث حقل البيانات لمسار Znode/MyConfig مع سلسلة عشوائية. نختار هنا تحديث Znode مع سلسلة معرف فريد عالمي (UUID) ، لأن مكالمات مولد UUID اللاحقة ستضمن توليد السلاسل الفريدة.
رمز فئة dataupdater.java كما يلي:
استيراد java.io.ioException ؛ استيراد java.util.uuid ؛ استيراد org.apache.zookeeper.keeperexception ؛ استيراد org.apache.zookeeper.watchedevent "LocalHost: 2181" ؛ سلسلة ثابتة Zoodatapath = "/MyConfig" ؛ Zookeeper ZK ؛ Public DataUpdater () يلقي IoException {try {zk = new zookeeper (hostport ، 2000 ، هذا) ؛ uuid string.public void run () رمي interruptedException ، keeperexception {بينما (صحيح) {string uuid = uuid.randomuuid (). {thread.sleep (5000) ؛ // sleep for 5 secs} catch (interruptedException e) {thread.currentThread (). interrupt () ؛}}} main static void main (string [] args) trowsioException ، interruptedException ، keeperexception {dataupdater dataupdater = new dataupdater () ؛ {system.out.printf ("/nevent receed: ٪ s" ، event.toString ()) ؛}}يتسبب الرمز أعلاه في أن يؤدي خادم ZookeEper إلى تشغيل حدث محدد. نظرًا لأن DataWatcher يقوم بتعيين مراقبة مسار Znode هذا ، فإنه يتلقى إخطارات لأحداث تغيير البيانات. ثم يسترجع البيانات المحدثة ، وإعادة تعيين المراقبة ، وطباعة البيانات على وحدة التحكم.
استخدم الأمر التالي لتجميع فئات DataWatcher و DataUpdater:
$ javac cp $ classpath datawatcher.java $ javac cp $ classpath dataupdater.java
لتنفيذ برنامج الشاشة والتحديث ، يجب فتح نوافذ طرفية. أرغب في تشغيل الشاشة أولاً لأنه ينشئ Znode of /myConfig (إذا لم يتم إنشاؤه في مساحة اسم Zookeeper). قبل تشغيل الشاشة ، تأكد من تشغيل خادم ZookeEper على المضيف المحلي.
في أحد النوافذ الطرفية ، قم بتنفيذ فئة المراقب عن طريق تشغيل الأمر التالي:
$ java cp $ classpath datawatcher
إخراج رسالة مماثلة لرسالة موضحة في لقطة الشاشة التالية:
كما هو موضح في لقطة الشاشة السابقة ، يتم إنشاء Znode Path/MyConfig بواسطة فئة DataWatcher. كما يطبع محتويات Znode ، ولكن ليس في وحدة التحكم ، لأننا لا نضع أي بيانات عند إنشاء Znode. عند إنشاء Znode ، يتلقى الشاشة في الفصل إخطارًا حدثًا من النوع nodecreated ، والذي يتم طباعته في وحدة التحكم. تستمر فئة DataWatcher في التشغيل والاستماع للأحداث على عقدة /myConfig من خادم Zookeeper.
دعنا ندير فئة DataUpdater في نافذة طرفية أخرى:
$ java -cp $ classpath dataupdater
بعد تسجيل تسجيل رسالة السجل الخاصة بـ ZookeEper الخاصة بـ Zookeeper إلى وحدة التحكم ، يتم تشغيل فئة DataUpdater دون المطالبة. يقوم بتعيين سلسلة UUID جديدة في حقل بيانات مسار ZookeEper/MyConfig. لذا ، راجع أنه كل 5 ثوانٍ ، يتم طباعة الإخراج المعروض في لقطة الشاشة أدناه في نافذة الطرفية التي تعمل على تشغيل datawatch:
يمكن أيضًا اختبار DataWatcher باستخدام قذيفة Zookeeper. استمر في تشغيل فئة DataWatcher في المحطة كما كان من قبل ، واتصل بقذيفة Zookeeper في محطة أخرى وقم بتشغيل الأمر الموضح في لقطة الشاشة التالية:
في المحطة التي يتم فيها تشغيل DataWatcher ، تتم طباعة الرسالة التالية:
ثلاثة أمثلة - شاشة الكتلة
يتم تقديم الخدمات الشائعة المقدمة عبر الإنترنت ، مثل البريد الإلكتروني ، ومنصات خدمة الملفات ، والألعاب عبر الإنترنت ، وما إلى ذلك ، بواسطة مئات أو الآلاف من الخوادم المتوفرة للغاية عبر مراكز البيانات المتعددة ، والتي غالبًا ما يتم فصلها جغرافياً. في مثل هذه المجموعة ، يتم إعداد بعض عقد الخادم المخصصة لمراقبة نشاط الخوادم التي تستضيف الخدمات أو التطبيقات في شبكة الإنتاج. في بيئة الحوسبة السحابية ، تسمى هذه العقد المراقبة التي يتم استخدامها أيضًا لإدارة البيئة السحابية وحدات التحكم السحابية. تتمثل إحدى الوظائف المهمة لعقد وحدة التحكم هذه في اكتشاف الفشل في خوادم الإنتاج في الوقت الفعلي وإخطار المسؤولين وفقًا لذلك ، واتخاذ التدابير اللازمة مثل الفشل في التطبيقات على الخادم الفاشل إلى خادم آخر ، مما يضمن تحمل الأخطاء وارتفاع التوفر.
في هذا القسم ، سوف نستخدم واجهة برمجة تطبيقات Zookeeper Java Client Client لتطوير نموذج مراقبة الكتلة الموزعة الحد الأدنى. يعد استخدام مفهوم Zookeeper الخاص بـ Znode Znode لبناء نموذج المراقبة هذا بسيطًا وأنيقًا ، كما هو موضح في الخطوات التالية:
يقوم كل خادم إنتاج بتشغيل عميل ZookeEper كخادم خفي. تتصل هذه العملية بخادم ZookeEper وإنشاء Znode سريع الزوال باسم (ويفضل أن يكون اسم الشبكة أو اسم المضيف) ضمن المسار المحدد مسبقًا لمساحة اسم Zookeeper (مثل /الأعضاء). تقوم عقدة Cloud Controller بتشغيل عملية مراقبة Zookeeper ، التي تراقب المسارات/الأعضاء وتستمع إلى أحداث من النوع NodeChildrenchanged. تعمل عملية الشاشة هذه كخدمة أو خفي ، وتعيين أو إعادة تعيين المراقبة على المسار ، وتنفذ منطقها لاستدعاء الوحدات النمطية المناسبة لاتخاذ الإجراءات اللازمة لمراقبة الأحداث. الآن ، إذا تم إيقاف تشغيل خادم الإنتاج بسبب فشل الأجهزة أو تعطل البرنامج ، يتم إنهاء عملية عميل Zookeeper ، مما تسبب في إنهاء الجلسة بين الخادم وخدمة ZookeEper. نظرًا لأن خصائص Znode سريعة الزوال فريدة من نوعها ، فإن خدمة ZookeEper ستحذف تلقائيًا Znode في المسار/الأعضاء كلما تم إغلاق اتصال العميل. يرفع حذف Znode في المسار حدث NodeChildrenchanged ، وبالتالي يتم إخطار عملية المراقب في وحدة التحكم السحابية. من خلال استدعاء طريقة GetChildren في المسار/الأعضاء ، يمكنك تحديد عقدة الخادم التي تم إغلاقها. يمكن لعقدة وحدة التحكم بعد ذلك اتخاذ تدابير مناسبة ، مثل إجراء منطق الاسترداد لإعادة تشغيل الخدمة الفاشلة في خادم آخر. يمكن بناء هذا المنطق للعمل في الوقت الفعلي ، مع ضمان ما يقرب من وقت التوقف عن الصفر والخدمات المتاحة للغاية.
لتنفيذ نموذج مراقبة الكتلة هذا ، سنقوم بتطوير فئتين Java. ستقوم فئة Clustermonitor بتشغيل الشاشة بشكل مستمر لرصد المسارات/الأعضاء في شجرة Zookeeper. بعد معالجة الحدث الذي تم رفعه ، سنقوم بطباعة قائمة Znode في وحدة التحكم وإعادة ضبط المراقبة. ستبدأ مجموعة ClusterClient أخرى الاتصال بخادم Zookeeper وإنشاء Znode سريع الزوال تحت /الأعضاء.
لمحاكاة مجموعة مع عقد متعددة ، نبدأ العديد من العملاء على نفس الكمبيوتر وإنشاء Znode freepheral باستخدام معرف العملية لعملية العميل. من خلال عرض هوية العملية ، يمكن لفئة ClusterMonitor تحديد عملية العميل التي تم إغلاقها والتي لا تزال العمليات موجودة. في الحالات العملية ، عادة ما تنشئ عمليات العميل Znode سريعة الزوال باستخدام اسم مضيف الخادم الذي يعمل حاليًا. يتم عرض رموز المصدر لهذين الفئتين أدناه.
يتم تعريف فئة clustermonitor.java على النحو التالي:
استيراد java.io.ioException ؛ استيراد java.util.list ؛ استيراد org.apache.zookeeper.createmode ؛ import org.apache.zookeeper.keeperexception ؛ import org.apache.zookeeper.watchedevent ؛ import org.asookeeper.watcher org.apache.zookeeper.zOokeeper ؛ clustermonitor public تنفذ Runnable {private static string sperthiproot = "/spems" ؛ Private Final Watcher ConnectionWatcher ؛ Watcher Final Final Watcher Kidswatcher ؛ private zookeeper zk ؛ {Overridepublic Void Process (حدث watchedevent) {if (event.gettype () == watcher.event.eventtype.none && event.getState () == watcher.event.eskerstate.syncconnected) {system.out.printf (/nevent trained: event.toSting () ؛ Watcher () {overridepublic process (حدث watchedevent) {system.out.printf ("/nevent receed: ٪ s" ، event.toString ()) ؛ if (event.gettype () == event.eventtype.nodechildrenchanged) عضوية ، هذا) ؛ هذا) ؛ الجدار ("!! تغيير العضوية الكتلة !!!") ؛ الجدار ("الأعضاء:" + أطفال) ؛} catch (keeperexception e) {رمي new runtimeexception (e) ؛} catch (interruptedException e) {thread.currentThread (). ZookeEper (Hostport ، 2000 ، ConnectionWatcher) ؛ // تأكد من وجود Znode الوالد (zk.exists (عضوية ، خطأ) == null) {zk.create (عضوية ، "clustermonitorroot". = zk.getChildren (عضوية ، kniderwatcher) ؛ system.err.println ("الأعضاء:" + أطفال) ؛} إغلاق الفراغ العام المزامن () {try {zk.close () ؛ message) ؛} public void run () {try {synchronized (this) {when (alive) {wait () ؛}}} catch (interruptedException e) { interruptedException ، keeperexception {if (args.length! = 1) {system.err.println ("الاستخدام: clustermonitor <المضيف: port>") ؛ system.exit (0) ؛} string hostport = args [0]يتم تعريف فئة 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.watcher ؛ org.apache.zookeeper.zoodefs.ids ؛ import org.apache.zookeeper.zookeeper ؛ طبقة عامة تُنطلق مراقب ، Runnable {private static string spisphisproot = "/sperze" ؛ zookeeper zk ؛ public clusterclient (String pid) ZookeEper (Hostport ، 2000 ، this) ؛} catch (ioException e) {E.PrintStackTrace () ؛} if (zk! = null) {try {zk.create (spemserphiroot + '/' + processid ، processId.getBytes () ، ids.open_acl_unsafe ، createMode. e) {e.printstacktrace () ؛}}} إغلاق void المزامن العام () {try {zk.close () ؛} catch (interruptedException e) {E.PrintStackTrace () ؛ void run () {try {synchronized (this) {بينما (صحيح) {wait () ؛}}} catch (interruptedException e) { {system.err.println ("الاستخدام: clusterclient <المضيف: port>") ؛ system.exit (0) ؛} string hostport = args [0] clusterclient (hostport ، processid) .run () ؛}}استخدم الأمر التالي لتجميع هاتين الفئتين:
$ javac -cp $ clustermonitor.java $ javac -cp $ clusterclient.java
لتنفيذ نموذج مراقبة الكتلة ، افتح محطتين. في واحدة من المحطات ، قم بتشغيل فئة Clustermonitor. في محطة أخرى ، يتم تنفيذ مثيلات متعددة عن طريق تشغيل فئة الكتلة في الخلفية.
في المحطة الأولى ، قم بتنفيذ فئة clustermonitor:
$ java -cp $ clustermonitorlocalhost: 2181
كما هو موضح في المثال السابق ، ترى رسالة سجل التصحيح من واجهة برمجة تطبيقات العميل. أخيرًا ، تبدأ فئة ClusterMonitor في مراقبة الحدث وإدخال المحتوى التالي:
قم الآن بتنفيذ خمس حالات من فئة Clusterclient لمحاكاة خمسة عقد من الكتلة. تقوم Clusterclient بإنشاء Znode سريع الزوال باستخدام معرف العملية الخاص به في مسار /أعضاء شجرة Zookeeper:
$ java -CP $ clusterclient localhost: 2181 2> & 1>/dev/null & [1] 4028 $ Java -CP $ clusterclient localhost: 2181 2> & 1>/dev/null & [2] -CP $ ClassPath ClusterClient LocalHost: 2181 2> & 1>/dev/null & [4] 4072 $ Java -CP $ clusterclient localhost: 2181 2> & 1>/dev/null & [5] 4084
المقابلة لهذا ، سيلاحظ أن فئة Clustermonitor تكتشف هذه مثيلات فئة الكتلة الجديدة هذه ، لأنها تراقب الأحداث على مسار /أعضاء شجرة Zookeeper. هذا يحاكي عقدة الانضمام إلى حدث في مجموعة حقيقية. يمكن رؤية الإخراج في محطة فئة الكتلة ، وهو ما يشبه ما هو موضح في لقطة الشاشة أدناه:
الآن ، إذا تم قتل عملية clusterclient.java ، فسيتم إنهاء الجلسة التي تحتفظ بها مع خادم ZookeEper. لذلك ، سيتم حذف Znode الزوال الذي أنشأه العميل. سيؤدي الحذف إلى حدوث حدث في Nodechildrenrenren ، والذي سيتم التقاطه بواسطة فئة Clustermonitor. هذا يحاكي سيناريو حيث تترك العقدة في الكتلة.
دعنا ننهي عملية clusterclient مع المعرف 4084:
$ Kill -9 4084
تُظهر لقطة الشاشة التالية الإخراج في محطة فئة ClusterMonitor. يسرد العمليات المتاحة حاليًا ومعرفات العملية التي تحاكي خادم الوقت الفعلي:
يوضح مثال تنفيذ نموذج مراقبة الكتلة البسيط والأنيق أعلاه القوة الحقيقية لـ Zookeeper. بدون Zookeeper ، سيكون تطوير مثل هذا النموذج الذي يمكنه مراقبة نشاط العقدة في الوقت الحقيقي مهمة شاقة حقيقية.