JavaRush /وبلاگ جاوا /Random-FA /نگهبان باغ وحش یا زندگی برای یک باغ وحش چگونه است
Viacheslav
مرحله

نگهبان باغ وحش یا زندگی برای یک باغ وحش چگونه است

در گروه منتشر شد
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 1

معرفی

برنامه های جاوا اغلب تنظیمات مختلفی دارند. برای مثال آدرس و پورت اتصال. برای مثال، اگر از کلاس Properties استفاده کنیم، ممکن است به این شکل باشد :
public static void main(String []args) {
	Properties props = new Properties();
	props.setProperty("host", "www.tutorialspoint.com");
	System.out.println("Hello, " + props.getProperty("host"));
}
و این کافی به نظر می رسد، زیرا ... می توانیم Properties را از فایل دریافت کنیم. و به نظر می رسد همه چیز با ما در یک دستگاه خوب پیش می رود. اما تصور کنید که سیستم ما شروع به تشکیل از سیستم های مختلف می کند که از یکدیگر جدا شده اند؟ به چنین سیستمی سیستم های توزیع شده نیز می گویند. در ویکی‌پدیا می‌توانید تعریف زیر را بیابید: سیستم‌های توزیع‌شده سیستم‌هایی هستند که اجزای آن در رایانه‌های شبکه‌ای مختلف قرار دارند که با یکدیگر ارتباط برقرار می‌کنند و اقدامات خود را با تبادل پیام با یکدیگر هماهنگ می‌کنند. می توانید به نمودار زیر نگاه کنید:
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 2
با این رویکرد، یک سیستم واحد به اجزاء تقسیم می شود. پیکربندی یک جزء مشترک جداگانه است. هر یک از اجزای دیگر به عنوان یک مشتری برای جزء پیکربندی عمل می کند. این مورد " پیکربندی توزیع شده " نامیده می شود. پیاده سازی های مختلفی از پیکربندی توزیع شده وجود دارد. و در بررسی امروز پیشنهاد می کنم با یکی از آنها که Zookeeper نام دارد آشنا شوید.
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 3

نگهبان باغ وحش

مسیر آشنایی با Zookeeper با وب سایت رسمی آنها آغاز می شود: zookeeper.apache.org در وب سایت رسمی باید به بخش « دانلود » بروید . در این قسمت آرشیو را با فرمت tar.gz دانلود کنید، به عنوان مثال “zookeeper-3.4.13.tar.gz”. tar یک قالب آرشیو سنتی برای سیستم های واحد است. gz - به این معنی است که gzip برای فشرده سازی آرشیو استفاده می شود. اگر ما روی یک ماشین ویندوز کار می کنیم، این نباید ما را آزار دهد. اکثر آرشیوهای مدرن (به عنوان مثال، 7-zip ) می توانند به خوبی با آنها در ویندوز کار کنند. بیایید محتویات را در یک دایرکتوری استخراج کنیم. در عین حال، تفاوت را خواهیم دید - روی دیسک در حالت استخراج شده تقریباً 60 مگابایت را اشغال می کند و ما یک آرشیو با اندازه حدود 35 مگابایت بارگیری کردیم. همانطور که می بینید، فشرده سازی واقعا کار می کند. اکنون باید Zookeeper را راه اندازی کنید. به طور کلی Zookeeper نوعی سرور است. Zookeeper را می توان در یکی از دو حالت اجرا کرد: مستقل یا تکراری . بیایید ساده ترین گزینه را در نظر بگیریم که به عنوان اولین گزینه نیز شناخته می شود - حالت مستقل. برای اجرای Zookeper، به یک فایل پیکربندی نیاز دارد. بنابراین، اجازه دهید آن را در اینجا ایجاد کنیم: [КаталогРаспаковкиZookeeper]/conf/zoo.cfg. برای ویندوز، ما از توصیه Medium استفاده خواهیم کرد: " نصب Apache ZooKeeper در ویندوز ". محتویات فایل پیکربندی چیزی شبیه به این خواهد بود:
tickTime=2000
dataDir=C:/zookeeper-3.4.13/data
clientPort=2181
بیایید متغیر محیطی ZOOKEEPER_HOME حاوی مسیر به دایرکتوری ریشه zookeper را اضافه کنیم (همانطور که در دستورالعمل های موجود در medium است)، و همچنین قطعه زیر را به متغیر محیطی PATH اضافه کنیم: ;%ZOOKEEPER_HOME%\bin; همچنین، دایرکتوری مشخص شده در dataDir باید وجود داشته باشد، در غیر این صورت Zookeeper نخواهد بود. قادر به راه اندازی سرور اکنون می توانیم با استفاده از دستور zkServer سرور را با خیال راحت راه اندازی کنیم. به لطف این واقعیت که دایرکتوری Zookeeper به متغیر محیط مسیر اضافه شده است، می‌توانیم دستورات Zookeper را از هر جایی فراخوانی کنیم، نه فقط از فهرست bin.
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 4

ZNode

همانطور که در " نمایش کلی Zookeeper " بیان شد، داده ها در Zookeper به صورت ZNodes (گره ها) نشان داده می شوند که در یک ساختار درختی سازماندهی شده اند. یعنی هر ZNode می تواند حاوی داده باشد و ZNode فرزند داشته باشد. می توانید اطلاعات بیشتری در مورد سازمان ZNode در مستندات Zookeeper بخوانید: " مدل داده و فضای نام سلسله مراتبی ". برای کار با Zookeeper و ZNode از Zookeeper CLI (واسط خط فرمان) استفاده خواهیم کرد . قبلا سرور را با استفاده از دستور zkServer راه اندازی کردیم. حالا برای اتصال، اجرا می کنیم، zkCli.cmd -server 127.0.0.1:2181 در صورت موفقیت آمیز بودن، یک جلسه اتصال به Zookeeper ایجاد می شود و تقریباً خروجی زیر را خواهیم دید:
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 5
جالب اینجاست که حتی بلافاصله پس از نصب، Zookeeper از قبل ZNode را دارد. مسیر زیر را دارد:/zookeeper/quota
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 6
اینها به اصطلاح « سهمیه » هستند. همانطور که در " Apache ZooKeeper Essentials " گفته شد، هر ZNode می تواند یک سهمیه مرتبط با خود داشته باشد و داده هایی را که می تواند ذخیره کند محدود می کند. ممکن است محدودیتی در تعداد znode ها و مقدار داده های ذخیره شده مشخص شود. علاوه بر این، در صورت تجاوز از این حد، عملیات با ZNode لغو نمی شود، اما هشداری در مورد تجاوز از حد دریافت می شود. توصیه می شود در مورد ZNode در " راهنمای برنامه نویس ZooKeeper: ZNodes " مطالعه کنید. چند مثال از آنجا که چگونه می توانید با ZNode کار کنید:
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 7
همچنین می خواهم توجه داشته باشم که ZNodes متفاوت هستند. ZNode های معمولی (مگر اینکه پرچم های اضافی را مشخص کنید) از نوع " مداوم " هستند. یک ZNode از نوع " Ephemeral Node " وجود دارد . چنین ZNode فقط برای مدت زمان جلسه اتصال Zookeeper که در آن ایجاد شده اند وجود دارند. یک ZNode از نوع " Sequence Node " وجود دارد . این ZNode ها با یک عدد از دنباله اضافه می شوند تا از منحصر به فرد بودن اطمینان حاصل شود. Sequence Node می تواند پایدار یا زودگذر باشد. اطلاعات پس زمینه کمی در مورد ZNode نیز در اینجا توصیه می شود: Zookeeper ZNodes – ویژگی ها و مثال .
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 8

ZNode Watcher

من همچنین می خواهم در مورد ناظران صحبت کنم. جزئیات مربوط به آنها در مستندات Zookeeper نوشته شده است: " ZooKeeper Watches ". به طور خلاصه، ناظر یک ماشه یک بار مصرف است که توسط یک رویداد ایجاد می شود. با بازیابی داده ها با انجام عملیات getData()، getChildren() یا exists() می توانیم یک تریگر به عنوان یک اقدام اضافی ایجاد کنیم. Zookeeper ترتیب پردازش رویداد را تضمین می کند. علاوه بر این، مستندات بیان می‌کنند که قبل از اینکه بتوانیم مقدار جدید ZNode را ببینیم، رویدادی در مورد تغییر مقدار قدیمی به جدید خواهیم دید. می توانید اطلاعات بیشتری در مورد Watchers در اینجا بخوانید: " Watches ZooKeeper – Features & Garantees ". برای انجام این کار، بیایید دوباره از CLI استفاده کنیم : فرض کنیم مقداری ZNode با مقداری داریم که در آن وضعیت برخی از سرویس‌ها را ذخیره می‌کنیم:
[zk: 127.0.0.1:2181(CONNECTED) 0] create /services/service1/status stopped
Created /services/service1/status
[zk: 127.0.0.1:2181(CONNECTED) 1] get /services/service1/status [watch]
stopped
اکنون، اگر داده ها /services/service1/statusتغییر کنند، ماشه یکباره ما فعال می شود:
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 9
جالب است که هنگام اتصال به Zookeeper، نحوه عملکرد ناظر را نیز می بینیم:
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
SyncConnected یکی از رویدادهای ممکن Zookeper است. جزئیات بیشتر در مورد آن را می توان در توضیحات API یافت.
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 10

Zookeeper و Java

ما اکنون درک اساسی از آنچه Zookeeper می تواند انجام دهد داریم. بیایید اکنون از طریق جاوا با آن کار کنیم، نه از طریق CLI. و برای این ما به یک برنامه جاوا نیاز داریم که در آن نحوه کار با Zookeeper را خواهیم دید. برای ایجاد برنامه، از سیستم ساخت پروژه Gradle استفاده می کنیم . با استفاده از " پلاگین Gradle Build Init " پروژه را ایجاد می کنیم. برای انجام این کار، بیایید این دستور را اجرا کنیم: gradle init --type java-application اگر Gradle از ما سؤالات واضح بخواهد، سپس مقادیر پیش فرض را ترک می کنیم (فقط Enter را فشار دهید). حالا بیایید اسکریپت ساخت را باز کنیم، i.e. فایل build.gradle. این شامل شرحی است از اینکه پروژه ما از چه چیزی ساخته شده است و به چه مصنوعاتی (کتابخانه ها، چارچوب ها) بستگی دارد. زیرا ما می خواهیم از Zookeeper استفاده کنیم، سپس باید آن را اضافه کنیم. بنابراین، اجازه دهید یک وابستگی به Zookeeper به بلوک وابستگی ها اضافه کنیم:
dependencies {
    implementation 'org.apache.zookeeper:zookeeper:3.4.13'
می توانید اطلاعات بیشتری در مورد Gradle در بررسی بخوانید: " A Brief Introduction to Gradle ". بنابراین، ما یک پروژه جاوا داریم، کتابخانه Zookeeper را به آن متصل کردیم. حالا یه چیزی بنویسیم همانطور که به یاد داریم، با استفاده از CLI چیزی شبیه به این را به هم وصل کردیم: zkCli.cmd -server 127.0.0.1:2181 بیایید ویژگی “server” را در کلاس App در روش اصلی اعلام کنیم:
String server = "127.0.0.1:2181";
اتصال یک اقدام فوری نیست. ما باید به نوعی در رشته اصلی اجرای برنامه منتظر بمانیم تا اتصال اتفاق بیفتد. بنابراین، ما به یک قفل نیاز داریم. بیایید آن را در زیر اعلام کنیم:
Object lock = new Object();
حالا به کسی نیاز داریم که بگوید ارتباط برقرار شده است. همانطور که به یاد داریم، وقتی این کار را از طریق CLI انجام دادیم، تماشاگر برای ما کار می کرد. بنابراین در کد جاوا همه چیز دقیقاً یکسان است. ناظر ما پیامی در مورد تکمیل موفقیت آمیز نمایش می دهد و از طریق یک قفل به همه افرادی که منتظر آن هستند اطلاع می دهد. بیایید یک ناظر بنویسیم:
Watcher connectionWatcher = new Watcher() {
	public void process(WatchedEvent we) {
		if (we.getState() == Event.KeeperState.SyncConnected) {
			System.out.println("Connected to Zookeeper in " + Thread.currentThread().getName());
			synchronized (lock) {
            	lock.notifyAll();
            }
		}
	}
};
حالا بیایید اتصال را به سرور zooKeeper اضافه کنیم:
int sessionTimeout = 2000;
ZooKeeper zooKeeper = null;
synchronized (lock) {
	zooKeeper = new ZooKeeper(server, sessionTimeout, connectionWatcher);
	lock.wait();
}
اینجا همه چیز ساده است. هنگام اجرای متد اصلی در رشته اصلی برنامه، قفل را گرفته و درخواست اتصال به نگهبان باغ وحش را می دهیم. در همان زمان، قفل را آزاد می کنیم و منتظر می مانیم تا شخص دیگری قفل را بگیرد و به ما اطلاع دهد که می توانیم ادامه دهیم. هنگامی که اتصال برقرار شد، ناظر کار خواهد کرد. او بررسی می‌کند که رویداد SyncConnected رسیده است (همانطور که به یاد می‌آوریم، این چیزی است که تماشاگر از طریق CLI دریافت کرده است)، و سپس پیامی می‌نویسد. در مرحله بعد، قفل را می گیریم (از آنجایی که نخ اصلی قبلاً آن را آزاد کرده است) و به همه رشته هایی که منتظر قفل هستند اطلاع می دهیم که می توانیم ادامه دهیم. رشته پردازش رویداد از بلوک همگام‌سازی شده خارج می‌شود و در نتیجه قفل را آزاد می‌کند. رشته اصلی یک اعلان دریافت کرد و پس از انتظار برای آزاد شدن قفل، به اجرا ادامه می‌دهد، زیرا تا زمانی که قفل را دریافت نکند، نمی تواند از بلوک همگام سازی شده خارج شود و به کار خود ادامه دهد. بنابراین، با استفاده از multithreading و Zookeeper API، می‌توانیم اقدامات مختلفی را انجام دهیم. Zookeeper API بسیار گسترده تر از آنچه CLI اجازه می دهد است. مثلا:
// Creation нового узла
String znodePath = "/zookeepernode2";
List<ACL> acls = ZooDefs.Ids.OPEN_ACL_UNSAFE;
if (zooKeeper.exists(znodePath, false) == null) {
	zooKeeper.create(znodePath, "data".getBytes(), acls, CreateMode.PERSISTENT);
}

// Получение данных из узла
byte[] data = zooKeeper.getData(znodePath, null, null);
System.out.println("Result: " + new String(data, "UTF-8"));
همانطور که می بینید، هنگام ایجاد یک گره می توانیم یک ACL را پیکربندی کنیم. این یکی دیگر از ویژگی های مهم است. ACL ها مجوزهایی هستند که برای اقدامات با ZNode اعمال می شوند. تنظیمات زیادی وجود دارد، بنابراین توصیه می کنم برای جزئیات بیشتر به اسناد رسمی مراجعه کنید: " مجوزهای ACL Zookeeper ".
نگهبان باغ وحش یا نحوه زندگی یک کارگر باغ وحش - 11

نتیجه

چرا این را خواندیم؟ زیرا Zookeeper در سایر فناوری های محبوب استفاده می شود. به عنوان مثال، آپاچی کافکا به Zookeeper نیاز دارد که می توانید در " راهنمای شروع سریع کافکا " در مورد آن مطالعه کنید. همچنین در پایگاه داده NOSQL HBase استفاده می‌شود که می‌توانید در « راهنمای شروع سریع HBase » اطلاعات بیشتری درباره آن بخوانید. در واقع، بسیاری از پروژه های دیگر از Zookeeper استفاده می کنند. برخی از آنها در " استفاده از Zookeeper در دنیای واقعی " ذکر شده است. امیدوارم به سوال "چرا" پاسخ داده باشم. اکنون مهمترین سوال این است: "بعدش چیست؟" ابتدا می توانید کتاب های زیر را با موضوع Apache Zookeeper مطالعه کنید: ثانیا، گزارش های ویدیویی بسیار خوبی در مورد Zookeeper وجود دارد. مشاهده توصیه شده: ثالثاً، چندین مقاله مفید وجود دارد که تصویر جهان را تکمیل می کند: این یک بررسی بسیار کوتاه است، اما به عنوان مقدمه، امیدوارم مفید واقع شود. #ویاچسلاو
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION