• بخش 7 – Node.JS ، درک عملکرد Node.js
بخش 7 – Node.JS ، درک عملکرد Node.js
1395/03/13 - 18:15:02 // Node.js // 0 نظر // 3056 بازدید

Node.js تمرکز خود را برای ساخت نرم افزارهای با کارایی بالا گذاشته است . در این بخش می خواهیم در مورد مشکل مقیاس I/O صبحت کنیم . سپس راه حل این مشکل را بصورت سنتی بررسی کرده و سپس راه حل آن را توسط Node.js بررسی خواهیم کرد .

بخش 7 Node.JS ، درک عملکرد Node.js

Node.js تمرکز خود را برای ساخت نرم افزارهای با کارایی بالا گذاشته است . در این بخش می خواهیم در مورد مشکل مقیاس I/O صبحت کنیم . سپس راه حل این مشکل را بصورت سنتی بررسی کرده و سپس راه حل آن را توسط Node.js بررسی خواهیم کرد .

مشکل بدست آوردن مقیاس در I/O

بگذارید تا نگاهی به تخمین زمان تقریبی دسترسی به داده ها از منابع مختلف در چرخه ی شرایط CPU بیاندازیم.

شما بوضوح می توانید ببینید که دسترسی به داده ی دیسک و شبکه کاملن با دسترسی داده توسط RAM و کَش CPU متفاوت می باشد .

اکثر نرم افزارها نیاز دارند تا داده ها را از منبع دیگری مانند دیسک خواند و یا از طریق شبکه به آن دسترسی داشته باشند ( بطور مثال یک کوئری دیتابیس ) . هنگامی که یک تقاضای HTTP دریافت می گردد و ما نیاز به بارگزاری داده از دیتابیس داریم ، معمولن این تقاضا نیاز به انتظار برای خواندن داده از دیسک و یا دریافت آن از شبکه خواهد داشت تا فراخوانی کامل گردد .

این زمان انتظار و همچنین اتصال باز ، منابع سرور ( حافظه و CPU ) را مصرف خواهد کرد . بنابراین بمنظور رسیدگی به تعداد زیادی درخواست از کلاینت های مختلف استفاده از این مدل وب سرور ، ما را با مشکل مقیاس پذیری I/O روبرو خواهد نمود .

روش سنتی

در سرورهای سنتی ، برای رسیدگی به هر تقاضا یک پردازش جدید ایجاد خواهد شد . ایجاد یک پردازش برای هر درخواست عملی بسیار گران قیمت هم از نظر CPU و هم RAM می باشد . نمایش این مفهوم را در شکل زیر مشاهده می نمایید . براساس آن برای پاسخ به درخواست HTTP A نیاز به داده های دیتابیس داریم . این خواندن اطلاعات ممکن است بصورت بالقوه زمان زیادی را بگیرد . برای این عمل ما نیاز داریم تا در هنگام خواندن داده از دیتابیس CPU و RAM را گرفته تا پاسخ دیتابیس برسد . بنابراین پردازش کند بوده و نیاز به سربار زیادی روی RAM خواهیم داشت . اینکار بسیار پرهزینه و طولانی بوده و در واقع دلیلی است بر اینکه نرم افزارهای جدید و مدرن از thread pool استفاده می کنند .

سرورهایی با استفاده از Thread Pool

سرورهای مدرن از یک thread که از thread pool می آید برای پاسخ به هر تقاضا استفاده می کنند . بنابراین ما سیستم عامل هایی داریم که thread ها را می سازند . هنگامی که درخواستی می آید ما یک Thread را به آن برای پاسخگویی اختصاصی می دهیم . و این thread برای این درخواست تا زمان پاسخگویی رزرو خواهد شد .

از آنجایی که ما سربار ساخت پردازش جدید را در هر بار از بین بردیم و thread ها از process ها سبک تر می باشند ، این روش بسیار بهتر از روش قبلی خواهد بود . از سال های پیش خیلی از وب سرورها از این روش استفاده کرده و در حال حاضر خیلی ها این راه را ادامه داده اند . بهرحال این روش هم عاری از مشکلات نیست . مجددن در این بین اتلاف RAM را در میان thread ها خواهیم داشت . در ضمن سیستم عامل نیاز دارد تعویض متنی مابین thread ها در هنگامی که بیکار هستند داشته باشد و در نتیجه در منابع CPU نیز مشکلاتی خواهیم داشت .

روش Nginx

ما دیدیم که ایجاد پردازش های جداگانه و thread های مجزا برای پاسخگویی به درخواست ها منابع سیستم عامل را اتلاف خواهد کرد . اما در Node.js ما برای پاسخگویی به درخواست ها تنها از یک thread منفرد استفاده خواهیم کرد . ایده ی Thread منفرد که می تواند بهتر از thread pool عمل کند یک ایده ی جدید از Node.js نیست . در اصل این ایده ساخته Nginx می باشد .

Nginx یک وب سرور با thread منفرد می باشد و می تواند درخواست های عظیمی که بصورت همزمان وارد می شوند را بررسی نماید .

مقایسه ای بین NGinx و Apache در تصویر زیر انجام شده که در واقع پاسخگویی هر دو به یک فایل استاتیک تکی می باشد .

همانطور که مشاهده می نمایید ، هنگامی که درخواست های همزمان زیاد می شود ، Nginx می تواند درخواست های همزمان بیشتری را در ثانیه نسبت به Apache بررسی نماید . و اما نکته ی جالب تر در مصرف حافظه در این دو مثال هست که در زیر مشاهده می نمایید :

با ورود درخواست های همزمان بیشتر Apache مجبور به اجرای thread های بیشتر بوده و بنابراین نیاز به حافظه ی بیشتری خواهد داشت ، اما همانگونه که مشاهده می نمایید Nginx بصورت پایدار در یک سطح باقیمانده است.

راز عملکرد Node.js

ایجا یک اجرای منفرد thread را در جاوا اسکریپت داریم . راهی که مرورگرهای وب بصورت سنتی عمل می کنند این است که اگر شما یک عمل با اجرای طولانی داشته باشید ( مانند timer انتظار برای اتمام و بازگشت یک کوئری از دیتابیس ) شما باید عملیات را با استفاده از یک callback ادامه دهید . در ادامه مثالی را بررسی می نماییم که در آن جاوا اسکریپت تابع setTimeout شبیه سازی یک عملیات طولانی را انجام خواهد داد . شما می توانید این کد را با استفاده از Node.js طبق آموزش های قبل اجرا نمایید .

این شبیه سازی در جاوا اسکریپت امکان پذیر است چرا که ما ابتدا یک first-class را تعریف کردیم و سپس یک تابع دیگر را به آن پاس دادیم . جذابیت کار آنجاست که شما یک first-class را با یک مفهوم closure ادغام نمودید . تصور کنید که ما درخواستی را که در واقع یک عمل طولانی مانند کوئری دیتابیس می باشد را ارسال نمودیم .

بدلیل استفاده از closure ، ما به درخواست کاربر صحیح بعد از اجرای عملیات طولانی دسترسی خواهیم داشت . تنها باید دو درخواست را در یک thread منفرد بررسی کنیم بدون اینکه سختی بکشیم . حال شما باید معنای این جمله را که گفتیم : ( Node.js عملکرد و کارایی بالایی دارد و از جاوا اسکریپت استفاده می نماید زیرا جاوا اسکریپت از توابع first-class و closure ها پشتیبانی می نماید) را فهمیده باشید .

سوالی که فورا ذهن شما را با خودش مشغول خواهد کرد این است که زمانی که شخصی به شما می گوید شما تنها یک thread منفرد برای بررسی درخواست دارید ، اما CPU من دارای چند هسته می باشد ! و استفاده از تنها یک thread باعث به هدر رفتن منابع می شود . و جواب این سوال ذهن شما این می شود که بله به هدر میرود !

اما در آینده در مورد توسعه و مقیاس پذیری سخن خواهیم گفت . در واقع بسیار ساده خواهد بود که ما از تمام هسته های CPU با استفاده از پردازش های جاوا اسکریپتی مجزا برای هر کدام از هسته ها توسط Node.js استفاده کنیم . این مهم است که بدانید مدیریت Thread ها در Node.js در سطح C وجود دارد اما تمامی اجراهای جاوا اسکریپت در یک thread منفرد خواهد بود .

شاد و سلامت باشید

محمد جعفری فوتمی

محمد جعفری فوتمی
معرفی نویسنده : محمد جعفری فوتمی

از سال 1382 بطور تخصصی در زمینه ی طراحی وب سایت کار کرده ام و در طی 12 سال گذشته تجربیاتی را کسب کرده ام که در هیچ کتاب و منبع آنلاینی یافت نمی شود ، تصمیم گرفته ام تا این تجربیات را در قالب مقالاتی به اشتراک بگذارم . امیدوارم مفید واقع شود .

امتیاز به مطلب
           
نظرات کاربران
ارسال نظر