شکل ۱- نمایی از پلتفرم Node.js در حال نصب روی ویندوز
چرا پلتفرم نود مهم است؟
با اینکه تاکنون پلتفرمهاي مشابهی با زبانهاي مختلف در این زمینه معرفی شدهاند، اهمیت Node.js در این است که رایان داهل و همکاران وی با استفاده از جاوا اسکريپت چنین پلتفرم سمت سروری را تولید کردهاند که بیاغراق، مورد استفاده تمام توسعهدهندگان وب تاکنون بوده است زيرا همه آنها برای انجام امور سمت کلاینت باید از جاوا اسکریپت استفاده ميکردند و معرفی نود باعث شد تا بسیاری به این فکر بیفتند که دیگر به زبان سمت سرور اختصاصی خود نیاز نداشته و با استفاده از جاوا اسکریپت، بسیاری از دردسرها کاهش خواهد یافت.
از طرف دیگر، پارادایم خاص جاوا اسکریپت برای کار با Callbackها و انجام امور ورودی/خروجی بهصورت non-blocking نیز در توجه توسعهدهندگان و گرایش بسیاری به سمت آن تأثیر بهسزایی داشته است.
برای روشنشدن میزان سودمندی نود، مثالي ذکر ميکنيم.
تصور کنید در یک سایت اینترنتی، هزاران کاربر با واردکردن URL سایت وارد آن شده و بسیاری دیگر، درخواستهاي AJAX بی شماری به وب سرور سایت مذکور ارسال ميکنند.
در این شرایط، هر درخواست یک رشته یا thread جدید در برنامه وب سرور مورد استفاده (که عموماً آپاچی خواهد بود) ایجاد کرده تا اسکریپتی را، براي نمونه PHP که به احتمال، حاوی پرسوجو از پایگاهداده یا چیزی شبیه به آن است، اجرا کند و نتیجه این اجرا را برای مرورگر درخواستکننده ارسال کند.
در این کاربرد دو مفهوم اصلی از اهمیت ویژهاي برخوردار هستند: یکی حافظه و دیگری ورودی/خروجی بلوکهکننده. زيرا هر thread اجرایی، حافظه بسیار زیادی را اشغالکرده و تعدد کاربران، امکان پرشدن حافظه سیستم و از کار افتادن خدمات مربوط را پیشميآورد.
همچنين، هر کدام از این رشتههاي پردازشی به عملیات ورودی/خروجی مانند دسترسی به پایگاهداده نیاز دارند که هرکدام به زمانی مشخص برای تکمیلشدن نیازمند است.
در بيشتر موارد نیز به دلیل بزرگبودن جدولهاي دادهاي و نتایج پرسوجوهای انجام شده، اسکریپت اجراکننده مجبور است تا بازگردانی دادهها از طرف پایگاهداده منتظرمانده و پس از دریافت، به اجرای بقیه دستورها بپردازد.
به همین دلیل، این عملیات، عملیات ورودی/خروجی بلوکه کننده نامیده ميشود و تأثیری بسیار منفی روی عملکرد کلی سرور خواهد داشت. نکته منفی این رویداد علاوه بر انتظار اسکریپت برای بازگردانی دادههاي درخواست شده، مصرف توانپردازشی و حافظه درحین انتظار است که در صورتی که در مقیاس بالا اتفاق بیفتد، باعث ناکارآمدی کلی سیستم خواهد شد (شکل۲).
شکل ۲- معماری گذشته وبسرورها
حال اگر راهی باشد که بتوان این رشتههاي پردازشی را حذف کرده و همه را در یک انباره بزرگ قرار داد، مشکل مصرف حافظه برطرف خواهد شد.
همچنين، در صورتی که بتوان تا زمانی که برای بازگردانی نتایج ورودی/خروجی (پرسوجو از پایگاهداده) منتظر هستیم، به انجام امور دیگر در اسکریپت خود بپردازیم مشکل بلوکه شدن نیز حذف شده و سرعت عملکرد به طور قابل توجهی افزایش خواهد یافت.
این دو مورد دقیقاً کارهایی است که Node.js به انجام آنها مبادرت ورزیده و به همین دلیل، اهميت بالایی در آینده برنامههاي کاربردی وب خواهد داشت.
یک سرور مبتنی بر Node.js، تمام اتصالهاي ورودی را در یک انباره مدیریت کرده و فریمورک پس زمینه نود، ميتواند حالات و شرایط این اتصالها را مدیریت کرده و براي نمونه، یک اتصال را به حالت «در حال انتظار» تبدیل کند.
همچنين، در پلتفرم نود از پارادیم حلقه رویداد و Callback برای انجام امور پرسوجو از پایگاه داده استفاده شده است تا انتظار برای پاسخ از پایگاه داده، منابع ارزشمند سیستم را بلوکه نکند.
در این حالت، فرآیند Callback به دادههاي بازگشتی از پایگاهداده تخصیص داده شده وهمزمان، نود به انجام امور دیگر ميپردازد که خود از هدر رفتن سیکلهای CPU بیشتری جلوگیری ميکند.
با استفاده از این روش، مرورگر سمت کلاینت تا فراهمشدن نتایج در حالت انتظار باقیميماند و با حالت درخواست دادهها از سرور threaded سنتی، هیچ تفاوتی احساس نمیکند.
پس از آماده شدن نتایج پرسوجو از پایگاهداده، کد مشخص شده بهعنوان Callback اجرا شده، اتصال مربوط را از انباره انتخابکرده و حالت آن را از وضعیت «درحال انتظار» خارج کرده و با استفاده از آن، دادههاي لازم را به مرورگر ارسال میکند. استفاده از چنین ساختاری علاوه بر کاهش مصرف حافظه، سرعت اجرای بالایی را نیز به ارمغان ميآورد (شکل۳).
شکل ۳- معماری قدیمی، اکنون با استفاده از node.js تغییر یافته است.
همانطور که ميدانید، برنامههاي تحت وب امروزی که بر مبنای AJAX کار ميکنند، بار کاری سنگینی را به سرورهای خود تحمیل ميکنند.
در صورتی که به برنامههاي گفتوگو یا بازیهاي تحت مرورگر چند بازیکنی توجه کنیم، متوجه خواهیم شد که آنها اتصالهاي همزمان بسیاری را ایجاد ميکنند که زمان کم پاسخگویی به هر کدام از آنها بسیار مهم و حیاتی است.
در چنین کاربردهایی است که قوت Node.js مشخص شده و روش مورد استفاده آن برای مدیریت امور بسیار پر اهمیتتر از گذشته بهنظر ميآید.
اگرچه تلاشهاي انجام شده برای استفاده از AJAX و Comet برای بهترکردن تجربه وب بسیار ارزنده بوده و سوکتهاي HTML5 نیز تلاش قابل تقدیری برای توسعه و ایجاد سهولت در پاسخ به این نیازمندیها بودند، اما تکمیلکننده این حلقه، استفاده از فناوريهاي جدید در سمت سرور بود که با معرفی و توسعه روزافزون Node.js به خوبی در حال شکلگیری است (شکل۴).
شکل ۴- جایگاه کنونی نود در بازار سرورها
در هر صورت، برای مقبولیت و گسترش روزافزون Node.js به اندکی زمان نیاز است تا توسعهدهندگانی که در چند سال اخیر و تاکنون بر مبنای پارادایمهاي سنتی AJAX به توسعه کد ميپرداختند، با روش جدید تطبیق پیدا کرده و به سوی آن گرایش پیدا کنند.
زمانی که سایتهاي معروف و برنامههاي وب مبتنی بر AJAX هر کدام سرور اختصاصی خود را داشته باشند، چندان دور نیست.
در صورتی که تجربه کار با AJAX، COMET یا جاوااسکریپت را داشتهاید، تجربه کار با Node.js را از دست ندهید.
مطمئن باشید که پس از آن، هیچ علاقهاي برای بازگشت به استفاده از PHP نخواهید داشت.
Node.js در یک نگاه
توسعه وب با استفاده از یک زبان داینامیک (جاوااسکریپت) که روي یک ماشین مجازی خیلی سریع با نام V۸ اجرا ميشود.
سرعت اجرای آن از Ruby ،Python و Perl بسیار بیشتر است. توانایی مدیریتکردن هزاران اتصال همزمان، با کمترین سربار و با استفاده از یک نرمافزار.
شایستگی ذاتی جاوااسکریپت در کار با event loopها با داشتن اشیاي درجه یک، قابل استفاده در توابع و همچنین نحوه بستنآنها که سالها توسط برنامهنویسان مختلف روي مرورگرها تمرین شده است.
تعدد افرادی که برنامهنویسی با استفاده از جاوااسکریپت را ميدانند یا در آن حرفهاي هستند. به جرأت ميتوان جاوااسکریپت را محبوبترین زبان برنامهنویسی حال حاضر دانست.
استفاده از جاوااسکریپت در سمت سرور به همراه استفاده از آن در سمت کلاینت، احتمال ناهمخوانی و بروز مشکلات و معضلات محیطهای ناهمگون برنامهنویسی را کاهشداده و امکان برقراری ارتباط دادهاي با استفاده از JSON میان هر دو طرف را فراهم ميسازد. استفاده از یک کد اعتبارسنجی فرم چه در سمت سرور و چه در سمت کلاینت واقعاً لذتبخش است.
مزایا
- مقیاسپذیر به هزاران اتصال فعال
- بسیار سریع (به خصوص در مقایسه با PHP و Ruby)
- امنیت بیشتر در مقابل بار اضافی اعمال شده به سرور (به خصوص در زمان وقوع حملههاي DDOS که بقیه نرمافزارهاي سرور مانند SSH قابل دسترسی و پاسخ دهنده باقی ميمانند)
- پارادایم ناهمزمان بسیار ساده، جذاب و آشنا
- نیاز نداشتن به درگیری با مسائلی مانند thread-safety
- عدم استفاده از Multithreading و به تبع آن، مواجه نشدن با باگهای قفلکننده
- جامعه توسعهدهندگان بسیار عظیم و کتابخانهها و ابزارهای توسعهداده شده غنی به همراه یک Package Manager قوی برای مدیریت ملحقات!
معایب
- پیچیدگی کد برنامه ناهمزمان (Asyncronous) و مشکل بودن یادگیری مفاهیم اولیه برای برنامهنویسان ناآشنا با مدل برنامهنویسی موازی.
- تأخیر بسیار بالا در صورت نیاز وظایف داخلی به اتمام عملیات محوله. به دلیل اینکه برنامه بهصورت تک رشتهاي اجرا ميشود، یک تابع با زمان اجرای طولانی ميتواند سرعت پاسخدهی کلی سیستم را به شدت کاهش دهد.
- نبود یک کتابخانه استاندارد جاوااسکریپت. برنامهنویسان جاوااسکریپت به شدت به استفاده آسان از آن عادت کردهاند، بدون اینکه به وارد کردن کتابخانه خاصی نیاز داشته باشند. بههمین دلیل، از هر چیزی در برنامهها پنج مدل مختلف وجود خواهد داشت که سردرگمی خاصی را ایجاد ميکند. حتی ماجولهاي قرارداده شده در هسته Node.js نیز هر کدام پنج نوع مختلف دارند که به تکامل سریعتر ميانجامد، اما درجه ابهام بالایی را نیز در پیخواهد داشت.
- سیستمهاي نهایی نوشتهشده با این فناوري بهشدت نسبت به مدل CGI، یعنی Apache+PHP یا Perl یا Ruby و... پیچیدهتر بوده و استثناهای مدیریتنشده ميتوانند کل فرآيند را متوقفکرده و نیاز به راهاندازی دوباره فرآيندهاي درحال کار روي کلاستر را الزامی سازند. یک کد باگ دار نیز ميتواند باعث خرابی فرآيند اجرایی مربوط شده و هر فرآيند درحال کار خراب، درخواستهاي بسیاری را بیپاسخ خواهدگذاشت که به تبع آن مقاومت کل سیستم در مقابل خرابی را کاهش داده و باعث کاهش کیفیت خدمات خواهد شد.