bahman jafarzadeh
bahman jafarzadeh
خواندن ۹ دقیقه·۱ سال پیش

‏swoole چگونه کار میکند؟



‏swoole چیست؟

‏Swoole یک افزونه برای PHP است که به توسعه‌دهندگان اجازه می‌دهد برنامه‌های PHP خود را به صورت (asynchronous) و بدون نیاز به سرور HTTP معمولی اجرا کنند.

این افزونه بر روی اندازه‌گیری‌های بالا، مقیاس‌پذیری و کارایی برنامه‌های PHP تأکید دارد.

‏Swoole از تکنولوژی Event-driven و Non-blocking استفاده می‌کند که به برنامه اجازه می‌دهد request ها را به صورت غیر همزمان پردازش کند. این بدان معناست که برنامه شما می‌تواند بدون انتظار برای پاسخ یک request، به request های دیگر پاسخ دهد. این قابلیت می‌تواند عملکرد و پاسخگویی برنامه را بهبود ببخشد.

همچنین، Swoole امکاناتی مانند پردازش‌های موازی، کشف و استفاده از هسته‌های چندگانه CPU و مدیریت آسان ترافیک شبکه را فراهم می‌کند.

از جمله استفاده‌های معمول Swoole می‌توان به توسعه سرورهای WebSocket، ساخت سرورهای API برای برنامه‌های تحت وب، ایجاد سرورهای پروتکل اختصاصی و انجام پردازش‌های موازی اشاره کرد.

منظور از Event-driven و Non-blocking چیست؟

‏Swoole از مدل همزمانی غیربلوکینگ و رویداد محور (non-blocking event-driven) استفاده می‌کند. این به این معناست که به جای انتظار برای پاسخ یک request قبل از پاسخ دادن به request بعدی، Swoole قادر است به صورت غیر همزمان (asynchronous) به چندین request همزمان پاسخ دهد.

وقتی برنامه‌ی Swoole اجرا می‌شود، یک event loop فعال می‌شود. Request ها به طور غیر همزمان به این event loop ها ارسال می‌شوند و Swoole بدون انتظار برای پاسخ request قبلی، به پردازش request جدید می‌پردازد. زمانی که پاسخ برای هر request آماده شد، سیگنالی (event) برای آن request به event loop ها ارسال می‌شود و برنامه بر اساس آن پاسخ را به درستی مدیریت می‌کند.

‏Swoole با استفاده از این روش همزمانی non-blocking قادر است تعداد بیشتری request را به صورت همزمان و با کمترین تأخیر پردازش کند. این مدل همزمانی باعث افزایش کارایی و پاسخگویی برنامه‌ها در بارهای سنگین و زمان‌های پاسخ مهم می‌شود.

تفاوت paraller و cuncurency در swoole


‏Parallel (موازی): زمانی از مفهوم موازی صحبت می‌کنیم که چندین وظیفه به صورت همزمان (به وقت واقعی) انجام شوند. به عبارت دیگر، وقتی کارها موازی انجام می‌شوند، هر دو وظیفه می‌توانند همزمان اجرا شوند و به این ترتیب زمان کل انجام کارها کاهش می‌یابد. این مفهوم بیشتر به ارتقاء کارایی و افزایش سرعت اجرای وظایف کمک می‌کند.

‏Concurrency (همروندی): در همروندی، وظایف به نظر می‌آیند که به صورت همزمان در حال اجرا هستند، اما در واقعیت اجرای آن‌ها ممکن است به صورت تعاقبی باشد. به این معنا که چندین وظیفه در حال اجرا هستند و زمانی که یکی از آن‌ها در انتظار یک حادثه خاص (مثلاً ورودی کاربر یا واحد زمانی) قرار دارد، وظایف دیگر ادامه اجرای خود را دارند. همروندی معمولاً در برنامه‌نویسی به افزایش پاسخگویی برنامه‌ها در مقابل حوادث آسنکرون (asynchronous) کمک می‌کند.

در کل، مفهوم Parallelism در Swoole به معنای پردازش موازی ریکوئست‌ها است، در حالی که Concurrency به معنای مدیریت همزمانی وظایف و ریکوئست‌ها به صورت موازی و به توجه به وقوع رویدادها می‌باشد. هر دو مفهوم اهمیت زیادی در بهبود کارایی و عملکرد برنامه‌های Swoole دارند و به تنظیمات و نیازهای خاص برنامه بستگی دارند.

‏thread ها در swoole

ممکن است برای شما این سوال پیش آید که چگونه پاسخ request های قبلی آماده میشود وقتی خود swoole مشغول بررسی request های بعدی میشود؟ و یا وقتی از یک thread استفاده میشود پس چگونه میتوان چندین request رو بررسی کرد؟

وقتی می‌گوییم Swoole از یک thread استفاده می‌کند، منظور این است که یک thread اصلی (main thread) برای اجرای کد برنامه وجود دارد.

وقتی یک request ورودی دریافت می‌شود، Swoole آن را در یک ترد کارگر (worker thread) ثبت می‌کند. سپس به بررسی request‌های بعدی می‌پردازد. این بررسی همه‌ی request‌ها را در یک thread انجام می‌دهد و به مدیریت کارها بر اساس وقوع رویدادها می‌پردازد. برای پاسخ دادن به request‌های قبلی، Swoole از حلقه رویدادها (event loop) استفاده می‌کند.

استفاده از یک thread اصلی و event loop به برنامه امکان می‌دهد به صورت غیر همزمان (asynchronous) عمل کرده و بدون انتظار برای پاسخ request ها، به بررسی و پاسخ دیگر request ها بپردازد.

در Swoole، هر worker در واقع یک فرآیند جداگانه است که می‌تواند توسط یک یا چند thread پشتیبانی شود. اما به طور پیش‌فرض، تعداد thread ها در هر worker برابر با یک است.

در این مدل، هر ریکوئست به صورت همزمان در یک ترد (worker) پردازش می‌شود.

از طرفی، هر worker می‌تواند چندین request را دریافت و پردازش کند. این به این معنی است که هر worker می‌تواند ریکوئست‌ها را به صورت همزمان دریافت کرده و در ترد خود پردازش نماید.

‏coroutine ها در swoole

‏swoole به صورت پیش‌فرض روی یک ترد اصلی (main thread) اجرا می‌شود و این ترد اصلی مسئولیت تسهیل ترتیب و مدیریت روند برنامه را دارد. این ترد اصلی با استفاده از event loop و منطق مدیریتی Swoole، ریکوئست‌ها را دریافت کرده و به تردهای درونی (Internal Threads) مربوطه ارجاع می‌دهد.

هر یک از این تردهای درونی به صورت همزمان یک ریکوئست را پردازش می‌کنند. این تردها از مفهوم (coroutines) و کنترل جریان همروندی (concurrency) استفاده می‌کنند تا بتوانند ریکوئست‌ها را به صورت همزمان پردازش کرده و پاسخ را به ترد اصلی ارسال کنند.

این روش امکان پردازش تعداد زیادی ریکوئست به صورت همزمان را فراهم می‌کند و به بهره‌وری منابع سیستم کمک می‌کند. همچنین، باعث افزایش کارایی برنامه در مواجهه با بارهای سنگین و زمان‌های پاسخ می‌شود.

تفاوت میان main thread و Internal Threads

تفاوت بین ترد درونی (internal thread) و ترد اصلی (main thread) در سیستم‌هایی که از مدل چند نخی پشتیبانی می‌کنند، به صورت زیر است:

ترد اصلی (Main Thread): این ترد اصلی برای اجرای بخش‌های اصلی برنامه استفاده می‌شود و مسئول تسهیل ترتیب و مدیریت روند برنامه است. معمولاً تمامی request ها و پردازش‌های اصلی در این ترد صورت می‌گیرد. برخی وظایف اصلی می‌توانند شامل مدیریت منابع، برنامه‌ریزی request ها، مدیریت حافظه و غیره باشند.

تردهای درونی (Internal Threads): این تردها برای اجرای موازی و همزمان بخش‌هایی از برنامه استفاده می‌شوند. زمانی که برنامه نیاز به پردازش همزمان چندین وظیفه دارد، تردهای درونی برای همزمان‌سازی اجراها استفاده می‌شوند. هر ترد درونی می‌تواند یک request یا وظیفه را به صورت همزمان پردازش کند. تردهای درونی معمولاً توسط ترد اصلی مدیریت می‌شوند و پاسخ‌ها به ترد اصلی ارسال می‌شوند. در کاربردهایی که نیاز به پردازش موازی و همزمان دارید، می‌توانید از تردهای درونی استفاده کنید تا بهترین استفاده از منابع سیستم را داشته باشید و کارایی برنامه خود را افزایش دهید.

در برنامه‌هایی که از مدل event loop استفاده می‌کنند، تردهای درونی (Internal Threads) نقش مهمی در اجرای event loop و پردازش‌های همروند دارند. این تردها به تنظیم و مدیریت event loop کمک می‌کنند و اجازه می‌دهند تا رویدادها و وظایف مختلف به صورت همزمان پردازش شوند.

‏Event loop به عنوان یک حلقه اجرایی (execution loop) عمل می‌کند و منتظر ورودی‌ها و رویدادها می‌ماند. وقتی یک ورودی وارد می‌شود، event loop آن را دریافت کرده و به ترد درونی مناسب ارجاع می‌دهد تا پردازش شود. این ترد درونی سپس وظیفه پردازش و پاسخ به ورودی را به عهده می‌گیرد.

تردهای درونی می‌توانند از مفاهیم همزمانی مثل coroutines استفاده کنند تا بهبود کارایی و پردازش‌های همروند را امکان‌پذیر کنند. این تردها معمولاً توسط ترد اصلی مدیریت می‌شوند و با استفاده از مکانیسم‌های مختلف می‌توانند وظایف مختلفی را به صورت همزمان اجرا کنند.

به طور خلاصه، تردهای درونی در برنامه‌هایی که از event loop استفاده می‌کنند، برای ایجاد همزمانی و اجرای پردازش‌ها در پس‌زمینه (background) و در پاسخ به رویدادها و ورودی‌ها نقش اساسی ایفا می‌کنند. این تردها با ترکیب با event loop به بهبود کارایی و پاسخگویی برنامه کمک می‌کنند.

بنابراین در swoole، هر worker یک ترد اصلی دارد که اجرای برنامه را در آن انجام می‌دهد. این ترد اصلی می‌تواند چندین ترد درونی (internal thread) را داشته باشد، ولی هر ترد درونی تنها متعلق به یک worker است و به تنهایی نمی‌تواند بین worker ها به اشتراک گذاشته شود.

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

توسعه بدون swoole

یکی از موضوع هایی که شاید باعث درک بهتر swoole و پی بردن به لزوم استفاده از آن شود٬ پرداختن به این موضوع است که بدون swoole چه اتفاقی رخ میدهد؟

وقتی که از Swoole استفاده نمی‌شود و یک برنامه PHP تحت وب راه‌اندازی می‌شود، وضعیت پردازش درخواست‌ها به صورت سریالی و بلوکه‌کننده عمل می‌کند. برای درک بهتر این موضوع، ابتدا به عملکرد معمولی یک برنامه PHP تحت وب بدون استفاده از Swoole می‌پردازیم:

  1. ایجاد Instance برای هر Request: وقتی یک کاربر درخواستی به سرور ارسال می‌کند، وب سرور (مثل Apache یا Nginx) یک instance جدید از برنامه PHP ایجاد می‌کند. این instance شامل تمام متغیرها و حالت‌های برنامه است و تا زمان اتمام پردازش درخواست کاربر باقی می‌ماند.
  2. پردازش ترتیبی (Sequential): در این حالت، هر درخواست در هر worker به صورت ترتیبی پردازش می‌شود. به عبارت دیگر، تا زمانی که یک درخواست به اتمام نرسد، درخواست‌های دیگر انتظار می‌کشند.
  3. بلوکه‌کننده (Blocking): وقتی کدی در برنامه به یک عملیات بلوکه‌کننده برخورد می‌کند (مثل خواندن از پایگاه داده یا انتظار برای ورودی کاربر)، برنامه تا زمان اتمام آن عملیات مسدود می‌شود و هیچ درخواست دیگری پردازش نمی‌شود.

این معمولاً منجر به عملکرد نامناسب در سرور‌های با فشار بالا می‌شود. به عنوان مثال، اگر یک درخواست زمان‌بری راه‌اندازی کند (مانند یک درخواست پایگاه داده با کمبود منابع)، تمامی درخواست‌های دیگر نیز متوقف می‌شوند و این منجر به افت کارایی و تجربه کاربری نامناسب می‌شود.

برای حل این مشکلات، ابزار‌هایی مانند Swoole به کمک می‌آیند:

  1. ‏Worker ها: Swoole از یک معماری توزیع شده استفاده می‌کند و یک تعداد کارگر (Worker) ایجاد می‌کند. هر کارگر می‌تواند چندین درخواست را به صورت همزمان پردازش کند.
  2. ‏Non-Blocking: در Swoole از عملیات‌های Non-blocking برای انجام عملیات‌های مستقل از هم (مانند ارسال درخواست به پایگاه داده) استفاده می‌کند. این به معنی این است که یک کارگر می‌تواند به جای مسدود کردن برنامه، به انتظار نتایج بلوکه نشده بپردازد و در این مدت به پردازش درخواست‌های دیگر بپردازد.
  3. عدم ایجاد Instance برای هر Request: در Swoole از یک instance پایه برای اجرای برنامه استفاده می‌کند و درخواست‌ها به کارگرها ارسال می‌شوند، بدون ایجاد instance جدید برای هر درخواست. این کاهش هزینه‌های ایجاد و نابودی instance و مدیریت حافظه را تسهیل می‌کند.

بنابراین، استفاده از Swoole به بهبود کارایی و پاسخگویی برنامه‌های تحت وب با تعداد درخواست‌های بالا کمک می‌کند، زیرا به صورت همزمان و بدون بلوکه‌کردن اجرای درخواست‌ها انجام می‌شود. این معماری منجر به بهره‌وری بالاتر، زمان پاسخ بهتر، و تجربه کاربری بهتر می‌شود، به خصوص در برنامه‌های با ترافیک بالا و عملیاتی مکرر.

event loopswooleasyncconcurrencyphp
شاید از این پست‌ها خوشتان بیاید