چرا node.js اینقدر طرفدار داره

nodejs

به جرأت میتونم بگم node.js انقلابی‌ترین حرکت در زمینه توسعه وب توی یکی دو سال گذشته بوده. node در github سومین پروژه از لحاظ محبوبیته و همین الان که من دارم این مطلب رو می‌نویسم این پروژه بیش از 4000 تماشاچی داره و بیش از 400 بار fork خورده و 100 ها ماژول براش نوشته شده و همه این اتفاقات در کمتر از یک سال و اندی که از شروع این پروژه می‌گذره افتاده.

اگر اخبار و تحولات توسعه وب رو دنبال کرده باشید حتما تا به حال مطالبی در موردش شنیدید اما ممکنه به اهمیت موضوع پی نبرده باشید. به عبارت دیگه اکثر افراد در وهله اول متوجه نمیشن که node چه چیز جدیدی برای ارائه داره و چی باعث محبوبیت اون شده.

اگر می‌خواهید در مورد node بیشتر بدونید در ادامه این مطلب با من همراه باشید.

حالا این node.js چی هست؟ یک فریم ورک جدید مثل jquery؟

نه اشتباه نکنید. node.js هیچ ربطی به مرورگر نداره و کدی که برای node نوشته میشه قرار نیست روی مرورگر اجرا بشه.

پس لابد یک زبان برنامه نویسی جدیده!

زبان جدید هم نیست. برنامه‌های node به زبان جاوا اسکریپت نوشته میشن. جاوا اسکریپتی که سمت سرور اجرا میشه. البته از node میشه برای نوشتن برنامه‌های غیر سروری هم استفاده کرد ولی بیشتر کاربردش برای نوشتن برنامه‌های سروری مخصوصا وبسرورهاست.

پس node رو میشه مثل php و python روی وبسرور نصب کرد.

نه. node مستقله. در واقع node خودش وبسرور داره و از وبسرور فعلی شما (مثلا آپاچی) استفاده نمیکنه.

میشه دقیقتر توضیح بدی یک برنامه تحت وب با node چه جوری اجرا میشه؟

node از طریق خط دستور (command line) اجرا میشه و برنامه شما رو اجرا میکنه. حالا برنامه شما میتونه از ماژول وبسرور node استفاده کنه و یک وبسرور راه بندازه.

ولی من هر کاری که بخوام با php و python و ruby و … میتونم انجام بدم.

خوب آره. node هم قرار نیست کار جدیدی که قبلا غیر ممکن بوده رو انجام بده. قرار هم نیست جای php و python و … رو بگیره. حداقل هنوز نه.

خوب پس چی باعث شده اینقدر طرفدار پیدا کنه؟

دلایل مختلفی داره. اگر ایده و هدف اصلی node و نحوه کارش رو بدونید خیلی از دلایلش مشخص میشه.

هدف node ایجاد راهکاری آسان برای نوشتن برنامه‌های مرتبط با شبکه با سرعت، کیفیت و مقیاس پذیری بالاست. پس دلیل اول محبوبیت node رو میشه این جوری نوشت که با node حتی برنامه‌نویس‌های غیرحرفه‌ای هم می‌تونن برنامه‌های حرفه‌ای برای شبکه بنویسند.

مگه node چه جوری کار میکنه؟

سوال خیلی خوبیه. برای اینکه به این سوال جواب بدیم اول باید ببینیم که بقیه وبسرورها چه جوری کار می‌کنند.

معمولا وبسرورها اینجوری کار می‌کنند که به ازای هر کانکشن یک thread جدید می سازند و این thread تا زمانی که کانکشن مربوطه باز باشه باقی می‌مونه. این کار بار پردازشی و مصرف مموری اضافی برای هر کانکشن ایجاد میکنه و به عبارتی باعث میشه تعداد کلاینت هایی که یک وبسرور همزمان میتونه پاسخگو باشه محدود باشه، عددی که به 10 هزار نمیرسه. برای همین این مشکل با نام «مسئله 10 هزار کانکشن همزمان» یا C10K معروفه. البته این مسئله‌ی جدیدی نیست. بحث سر این مسئله و راهکارهای موجود از حدود 11 سال پیش وجود داشته. وبسرورهای جدید نظیر nginx و lighttpd و cherokee این مشکل رو حل کردند. و البته node.js هم با توجه به هدف اولیه ای که داشته جزو اون دسته از وبسروهایی محسوب میشه که این مشکل رو ندارند.

و این مشکل چطور حل شده؟

قبل از اینکه به راه حل مشکل بپردازیم باید ببینیم مشکل از کجا ناشی میشه.

مشکل از اونجایی ناشی میشه که دریافت، پردازش و پاسخ دادن به یک درخواست از یک کلاینت اونقدر طول میکشه که نمیشه برای دریافت کانکشن بعدی منتظر اتمام کار کانکشن قبلی موند. بنابراین وبسرورها برای پاسخ به کلاینت جدید یک thread جدید ایجاد می‌کردند.

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

دقیقا. اما مسئله اینجاست که پردازنده ها به اندازه کافی سریع هستند و اون چیزی که باعث کند شدن این روند میشه I/O هست. یعنی عملیات ورودی و خروجی، چه از شبکه و چه از سیستم فایل.

اونوقت مشکل IO رو چطور حل کردند؟

برای رفع این مشکل به جای اینکه عملیات ورودی/خروجی مستقیما انجام بشه از معماری رویداد گرا برای پیاده سازی IO استفاده میشه. به عبارتی به جای اینکه منتظر نتیجه IO بمونیم یک رویداد برای دریافت نتیجه تعریف می‌کنیم و اجرای برنامه ادامه پیدا میکنه. به این ترتیب عملیات های ورودی/خروجی باعث بلاک شدن اجرای برنامه نمیشه. و node هم با همین معماری نوشته شده برای همین اولین جمله ای که در توصیف node در سایتش نوشته شده اینه: «Evented I/O for V8 JavaScript»

اگر وبسرورهایی مثل nginx قبلا این مشکل رو حل کردند پس node چه حرفی واسه گفتن داره؟

درسته که این مشکل قبلا حل شده ولی این مشکل فقط در سطح وب سرور حل شده. منظورم اینه که مثلا وقتی میخوای یک برنامه php رو روی این وبسرور اجرا کنی با اینکه وبسرور برای هر درخواست thread ایجاد نمیکنه ولی php این کار رو میکنه.

پس با این حساب node راهکاری برای برنامه نویسی رویداد گرای IO سمت سرور فراهم کرده.

درسته. البته node اولین نیست. قبل از node این سبک برنامه نویسی با Twisted در python و EventMachine در ruby هم امکان پذیر بوده. خود برنامه نویس node هم گفته که توی طراحی node از این دو پروژه ایده گرفته.

پس چرا اونها به اندازه node معروف نشدند؟

دلایل مختلفی داره.

یکی اینکه برنامه های node به زبان جاوا اسکریپت نوشته میشن. و اکثر کسانی که تو کار توسعه وب هستند کم و بیش با این زبان آشنایی دارند. علاوه بر این زبان جاوا اسکریپت زبان فوق العاده ای برای معماری رویداد گراست و اکثر کسانی که قبلا با جاوا اسکریپت برای مرورگر کد نوشتند برنامه نویسی رویداد گرا با جاوا اسکریپت رو تجربه کردند.
یک مزیت دیگه جاوا اسکریپتی بودن اینه که برای برنامه نویسی سرور و کلاینت از یک syntax استفاده میشه که قطعا راحت تره و حتی بخش‌هایی از کد رو برای هر دو طرف میشه استفاده کرد (مثل اعتبار سنجی فرمها).
دیگه اینکه node برای موتور جاوا اسکریپت از V8 استفاده میکنه که جزو سریعترین مفسرهای اسکریپتی محسوب میشه و حتی از پایتون هم سریعتره.
دلیل دیگه اینه که node از اول با این ایده یعنی رویداد گرا طراحی شده نه به صورت یک library جداگانه، بنابراین کار باهاش خیلی راحت تره.

ولی به درد من نمی‌خوره. من هیچ وقت 10 هزار تا بازدیدکننده همزمان ندارم. مشکلی هم با سرعت برنامه هام ندارم.

مسئله فقط سرعت و مقیاس پذیری نیست.

برای مقایسه یک برنامه php رو در نظر بگیرید. هر بار که یک درخواست به سرور ارسال میشه برنامه php اجرا میشه و یک نتیجه ای رو بر میگردونه و تموم میشه. ولی برنامه ای که با node نوشته شده یکبار اجرا میشه و تو حافظه می‌مونه. اینجا به جای اینکه وب‌سرور برنامه رو اجرا کنه این برنامه هست که وب‌سرور رو اجرا می‌کنه. بنابراین برنامه به همه کانکشن‌های سرور دسترسی داره و مثلا میتونه اطلاعاتی رو از یک کلاینت بگیره و به یک کلاینت دیگه بفرسته بدون اینکه از دیتابیس یا shared memory استفاده کنه. برای مثال با این ویژگی میشه بدون استفاده از دیتابیس و یا هیچ ابزار جانبی دیگه ای یک چت روم نوشت.
یک مثال دیگه از قابلیت‌های node حالتیه که برای همه درخواست ها احتیاج به یکسری اطلاعات مشترک داریم که باید از دیتابیس خونده بشه. با php یا باید همه اطلاعات هر بار از دیتابیس خونده بشه و یا اینکه یکبار کش بشه و دفعات بعد از کش خونده بشه. ولی با node میشه این اطلاعات رو یکبار خوند و برای همه کانکشن ها ازش استفاده کرد.

در ضمن امروزه با فراگیر شدن وب 2 استفاده از comet هم رایج تر شده. برای پیاده سازی comet در واقع یک کانکشن به سرور برقرار میشه و باز نگه داشته میشه. که با وبسروری مثل آپاچی با زیاد شدن تعداد کانکشن‌ها عملا این کار غیر ممکن میشه. ولی node برای این کار فوق العادست.

نکته دیگه ای که در مورد node وجود داره تعدد ماژول هاشه. تقریبا توی هر زمینه ای که بخواهید برای node ماژول پیدا میشه.

برای نمونه socket.io ماژولی برای پیاده سازی ارتباط دو طرفه بین سرور و مرورگر هست. این ماژول برای پیاده سازی comet تقریبا از همه روش‌های موجود نظیر Ajax long pulling و Flash Socket و WebSocket پشتیبانی می‌کنه و بسته به اینکه مرورگر شما با کدامیک از این روش‌ها سازگار باشه خودش بهترین روش ممکن رو انتخاب می‌کنه. و تقریبا همه مرورگرهای رایج رو پشتیبانی می‌کنه.
با این ماژول به راحتی میشه ارتباطات دوطرفه و بلادرنگ بین سرور و کلاینت برقرار کرد.

خلاصه اینکه ابزارها و ماژول های فوق العاده ای برای node نوشته شده نظیر express و hummingbird و vows و ماژولهای مختلفی برای کار با دیتابیس‌های مختلف. حتی به خاطر تعدد ماژولها برای node ابزار مدیریت بسته ها (node package manager) هم نوشته شده تا نصب و بروزرسانی ماژول‌ها راحت تر باشه.

خوب دیگه فکر کنم همینقدر برای شروع کافی باشه.

برای حسن ختام چند تا لینک مرتبط هم معرفی میکنم:

برچسب‌ها:

25 دیدگاه برای “چرا node.js اینقدر طرفدار داره”

  1. محمد صالح گفته:

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

    کلا برای پروژه های خاص و با بستر خاص استفاده بشه.

  2. بامداد دشت بان گفته:

    سلام
    چند سالی است که روی مسائلی که مطرح کردید کار می کنم و حتی وب سروری کامل به زبان پی اچ پی برای پیاده سازی کامیت نوشتم که در وبلاگم و وب لاگ مشترک من با اشکان با نام پروژه کلوب می تونید ببینید.
    با آمدن مفهوم وب ساکت در اچ تی ام ال 5 این تکنولوژی ها ارزش خود را از دست می دهند
    با وجود تکنولوژی های مثل jBoss و Glassfish application server که از تمامی این تکنولوژی ها به صورت یکپارچه و گسترده با استفاده از معماری J2EE پشتیبانی می کند دنبال کردن چنین تکنولوژی های وقت طلف کردن است.
    این مفاهیمی که مطرح کردید با thread pool حل شده اند و خوب ابعاد استفاده از تکنولوژی هایی که مطرح کرده اید برنامه نویس را به استفاده از معماری های جامع مثل j2ee راهنمایی می کند به علت گسترده بودن ابعاد پروژه
    موفق باشید
    خوشحالم که پس از چند سال کسی راجع به کامیت چیزی نوشت

  3. علی گفته:

    @محمد صالح:
    چون این تکنولوژی هنوز خوب جا نیافتاده هاستینگ اشتراکی براش خیلی کمه. ولی احتمالا آینده روشنی داره.

  4. علی گفته:

    @ بامداد دشت بان:
    سلام.

    بذار چند تا چیز رو روشن کنم.
    node یک ابزار هست که میشه ازش برای پیاده سازی کامت استفاده کرد.
    کامت یک مدل از نحوه ارتباط با سرور برای وب اپلیکیشن‌هاست.
    و WebSocket یک روش استاندارد برای پیاده سازی کامت هست.
    پس هیچ موضوعیت نداره که بگیم «WebSocket جای node رو میگیره»!
    node.js هیچ منافاتی با WebSocket نداره. بلکه حتی یکی از بهترین ابزارها برای پیاده سازی WebSocket هست.

    از جاوا سر رشته ای ندارم و در موردش نظر نمیدم.

    اما در مورد thread pool در واقع هیچ کار شاقی انجام نمیده و فقط جلوتر thread ها رو ایجاد میکنه که آماده باشه و وقت کمتری گرفته بشه ولی توی مصرف حافظه تاثیری نداره و از لحاظ مقیاس پذیری اصلا قابل مقایسه با معماری رویدادگرا نیست.

  5. سعید گفته:

    سلام آقای فرهادی میشه email خودتون رو برای من ارسال کنید

  6. من گفته:

    سلا.عجب وبلاگ گردن کلفتی داری.منظورم اینه که جالب و عالی هستش.

  7. احمد گفته:

    سلام عزیز
    ببخشید که اینجا توی این پست کامنت می‌ذارم و سوال می‌پرسم
    فکر کنم سایت شخصی‌تون مشکل دار شده چون تمام صفحاتش redirect می‌شن به صفحه اصلی در واقع. مثلن: این صفحه
    http://farhadi.ir/works/jalalijscalendar
    هم محتویات صفحه اول رو نمایش می‌ده. من می‌خواستم نسخه جدید تقویم فارسی رو بگیرم اما نتونستم. امکانش هست کمکم کنید؟

    ممنون.

  8. علی گفته:

    @احمد:
    سلام
    ممنون که اطلاع دادی.
    درستش کردم.

  9. رز سیاه گفته:

    سلام
    خدایی وبلاگ باحالی داری و از نظر علمی که نگو بعضی چیزاش رو خوندم هنگ کردم

    ایشالا همیشه شاد باشی

  10. نبی گفته:

    مقاله بسیار جالبی بود دستت درد نکنه.
    من بیشتر با اینش حال کردم: “ارتباطات دوطرفه و بلادرنگ بین سرور و کلاینت برقرار کرد” این میتونه خیلی مفید باشه برای web application ها.
    راستی نمیدونی فیس بوک از چه تکنیکی استفاده میکنه برای همین ارتباط دوطرفه و بلادرنگ …؟! منظورم بعضی اوقاته که بدون رفرش صفحه یکمرتبه notification جدید میاد یا comment جدید ظاهر میشه!

  11. علی گفته:

    در مورد فیس بوک نمیدونم ولی به احتمال خیلی زیاد از یکی از همین تکنیک های کامت استفاده میکنه. شاید هم تکنیک استفاده شده بسته به مرورگر فرق کنه.
    socket.io هم از شش روش پشنیبانی میکنه که به صورت خودکار بهینه ترین روش رو خودش انتخاب میکنه.

  12. کسری مبصری گفته:

    سلام علی جان ،
    دستت درد نکنه . مقاله جالبی بود .
    انشاءالله موفق باشی .

  13. احسان گفته:

    سلام علی جان

    با اجازه از date picker خوبی که نوشتی استفاده می کنم.

  14. بهنام گفته:

    چند وقتی بود که دنبال یک رفرنس خوب درباره nod.js میگشتم .
    ممنونم که وقت گزاشتید و نوشتید ، بسیار عالی

  15. ? گفته:

    سلام چرا چند ماهه تو وبلاگتون پست جدید نمی زنید؟
    علمتون رو به ما هم منتقل کنید!
    موفق باشید

  16. افاضاتی گفته:

    البته تو چیزهایی مثل Twisted هم میشه push داشت ولی من یکی با سر عت زیادش خیلی حال کردم.

  17. حمید گفته:

    سلام علی جان
    از تقویم نازت و مطالب زیبات ممنون امیدوارم موفق و پیروز باشی

  18. افشین گفته:

    دمت گرم علی. فوق‌العاده بود…

  19. چالیست گفته:

    ممنون
    ممنون می شم اگه بخش عضویت با ایمیل هم بزارید که وقتی مطلب می فرستی ایمیل بشه

    ممنون باز

  20. محمد گفته:

    سلام دوست عزیز
    بالاخره شما با تقویم فارسی در Breezing form به کجا رسیدید؟ مشکل تقویم فارسی در Breezing form حل شد؟

  21. behnam گفته:

    ممنون از اطلاعات خوبتون. من مدتی هست که پروژه nodejs رو دنبال می کنم. در این مدت مطلب فارسی به این کاملی ندیده بودم. ممنون از اطلاعات خوبتون.

  22. M.J گفته:

    سلام
    یه سوالی داشتم در مورد تقویم شمسی ای که نوشتین
    یه اسکریپتی هست که به عنوان تقویم با قابلیت رویداد دهی هست به آدرس:
    http://www.web-delicious.com/jquery-event-calendar/

    به نظرتون میشه تاریخ شمسی رو هم روی این تقویم پیاده کرد؟ خیلی زمان میبره؟
    اگه بشه اینکارو کرد، اسکریپت محضری میشه برای شمسی تقویم ها!

    خوشحال میشم جواب بدین و نظرتون رو بدین…

  23. سید محسن حائری گفته:

    سلام

    بابت مطلب مفیدتون ممنون.

  24. عباس گفته:

    خیلی مفید و جالب بود. دست شما درد نکنه.

  25. behnam گفته:

    سلام ببخشید شما هنوز اینجا سر میزنین آقای فرهادی ؟ آخه دیدم آرشیوتون ماله 89 هستش اگه هنوز اینجایین لطفا خبرم کنین . مرسی

دیدگاهی بنویسید