در قسمت اول آموزش ساخت Queue در PHP به طور کامل صف بندی و اهمیت آن در اپلیکشن ها را بررسی کردیم و حالا نیاز است که در قالب مثال در کد php صف بندی را پیاده سازی و استفاده کنیم.
مرور کلی
queue ها به شما این امکان را می دهند تا پردازش کارها و عملیات زمان بر همچون ارسال ایمیل را به تعویق انداخته و بدین وسیله سرعت پاسخ دهی به درخواست های ارسالی به اپلیکیشن تحت وب خود را به شکل چشم گیری افزایش دهید.
در آموزش ساخت Queue در PHP قصد داریم به شما نحوه صف بندی کارها در PHP و نحوه پیاده سازی یک مثال ساده از مدیریت پروسه ها با Queue در PHP را به شما نمایش بدیم.
این صف (Queue) ها می توانند در دیتابیس (MySQL ..) یا Redis (نوعی دیتابیس NoSQL که در رم ذخیره می شود.) ذخیره شوند .
پیاده سازی و ساخت Queue در PHP
از آنجایی که تعریف صف ها بسیار ساده است, تقریبا می توانید از هر محل ذخیره سازی داده ای استفاده کنید. حتی می توانید از یک آرایه php معمولی نیز بهره ببرید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php class Queue { protected $_storage = array(); public function addItem( $item ) { $this->_storage[] = $item; } function getItem() { return array_shift($this->_storage); } }; ?> |
احتمالا اسکریپت بالا برای صف هایی که بسیار کوتاه هستند قابل استفاده باشد. که خب مطمیمنا متغییر $queue
با رفرش صفحه از بین می رود و دیگر وجود نخواهد داشت !
بنابراین نیاز داریم که یک مخزن ذخیره اطلاعات مداوم و یک آداپتور PHP برای دسترسی به آن را داشته باشیم. از روی تجربه این محل ذخیره سازی می تواند:
- یک فایل متن ساده ; یک فایل log باشد.
- اینباکس Gmail , به فرض اگر نیاز به پردازش پیام های ایمیل را دارید که پشت سر هم می آیند, بنابراین نیازی به پر کردن صف هم نخواهید داشت.
- راه حل های مخصوص صف بندی مثل Apache ActiveMQ یا Apache Kafka
- یک وب سرویس بر پایه ذخیره سازی مثل iron.io
- یک جدول دیتابیس که به نظر ما بهترین و ساده ترین راه است.
برای پیاده سازی صف هایمان, قصد داریم از توابع Semaphore استفاده کنیم.با این توابع دیگر نیاز نیست که همزمان عملیات مختلف را هندل کنیم. آنها در بالاسر, همه آنچه برای شروع نیاز داریم را مدیریت می کنند.
طراحی یک صف پیام
برای ساخت صف در PHP , نیاز داریم که منطق کارمان را به دو بخش تقسیم کنیم.
اول, یک سری پیام را به صف اضافه کنیم . دوم, نیاز داریم که با پروسه های خودمان پیام های داخل صف را بخوانیم.
ساخت Queue در PHP
راه اندازی یک صف پیام در PHP همانطور آسان است که یک شماره دلخواه را انتخاب می کنیم و سپس به یک هندلر از ریسورس های سیستم پیام دسترسی پیدا می کنیم.
برای شروع, یک فایل ثابت برای اینکار می سازیم :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Queue { /** * Stores our queue semaphore. * @var resource */ private static $queue = NULL; /** * getQueue: Returns the semaphore message resource. * * @access public */ public static function getQueue() { # Some unique ID define('QUEUE_KEY', 12345); # Different type of actions define('QUEUE_TYPE_START', 1); define('QUEUE_TYPE_END', 2); # Setup the queue self::$queue = msg_get_queue(QUEUE_KEY); # Return the queue return self::$queue; } } |
کلاس Queue
راه ساده ما برای دسترسی به یک صف است. ما یک ثابت با مقدار عددی دلخواه را به منظور شناسایی صف, تعریف کردیم و دو مقدار عددی دیگر نیز برای دسترسی به نوع پیام در صف مورد استفاده قرار خواهیم داد.
راه اندازی سیستم پیام
حالا که کلاس کاربردی Queue
خود را داریم, نیاز است که یک ساختار داده ساده برا هر یک از پیام هایمان را ایجاد کنیم. زمانی که پیام را به یک صف منتقل می کنیم, آبجکت ما به صورت سریال شده (serialized
) در می آید. بنابراین می توایم هر آبجکتی را که نیاز داریم استفاده کنیم و هر متدی را که می خواهیم بر روی این آبجکت صدا بزنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Message { /** * @var private */ private $key = ''; private $data = array(); /** * Constructor: Pass over the data we need */ public function __construct($key, $data) { $this->key = $key; $this->data = $data; } /** * getKey: Returns the key */ public function getKey() { return $this->key; } } |
افزودن پیام به صف (Queue)
برای افزودن پیام به صف, نیاز است که یک متد دیگر به کلاس Queue
اضافه کنیم که یک کلید را برای شناسای صف و یک آرایه دلخواه از داده ها را که قصد پاس دادن آن به کلاس Message
خود داریم را, دریافت می کند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/** * addMessage: Given a key, store a new message into our queue. * * @param $key string - Reference to the message (PK) * @param $data array - Some data to pass into the message */ public static function addMessage($key, $data = array()) { # What to send $message = new Message($key, $data); # Try to send the message if(msg_send(self::$queue, QUEUE_TYPE_START, $message)) { print_r(msg_stat_queue(self::$queue)); } else { echo "Error adding to the queue"; } } |
کار با صف پیام ها
برای کار با صف پیام ها, نیاز داریم که یک کلاس Worker
برای خواندن هر یک از پیام ها, پردازش عملیات و اجرای یک متد کامل با استفاده از آبجکت Message
ای که خواندیم, ایجاد کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
class Worker { /** * Store the semaphore queue handler. * @var resource */ private $queue = NULL; /** * Store an instance of the read Message * @var Message */ private $message = NULL; /** * Constructor: Setup our enviroment, load the queue and then * process the message. */ public function __construct() { # Get the queue $this->queue = Queue::getQueue(); # Now process $this->process(); } private function process() { $messageType = NULL; $messageMaxSize = 1024; # Loop over the queue while(msg_receive($this->queue, QUEUE_TYPE_START, $messageType, $messageMaxSize, $this->message)) { # We have the message, fire back $this->complete($messageType, $this->message); # Reset the message state $messageType = NULL; $this->message = NULL; } } /** * complete: Handle the message we read from the queue * * @param $messageType int - The type we actually got, not what we desired * @param $message Message - The actual object */ private function complete($messageType, Message $message) { # Generic method echo $message->getKey(); } } |
استفاده از صف بندی و فریمورک Slim
حالا که صف Queue خود را دایم و کلاس های Message
و worker
ما هم آماده است – نیاز است که ما فقط همه را یکجا قرار بدیم. برای این منظور از فریمورک Slim در اینجا استفاده می کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$app = new SlimSlim(); /** * Handle all POST to /create * * @param key string */ $app->post('/create', function() { # Get the key $key = $_POST['key']; # Setup some data $data = array( 'time' => time(), 'key' => $key, 'request' => 'start' ); # Add the message into the queue Queue::addMessage($key, $data); }); # Run the application $app->run(); |
حالا ما یک اپلیکیشن REST داریم که می توانیم درخواست های POST را به /create
ارسال کنیم. برای شروع کار Worker
ما می توانیم یک تسک cron را برای فراخوانی کلاس Worker خودمان ایجاد کنیم.
1 |
$worker = new Worker; |
خب همین قدر بود, می توانیم پیام ها خودمان را به صف اضافه کنیم. و ببنیم worker ما خروجی را با کلید مورد نظر برای ما برگشت می دهد.
جمع بندی
همانطور که دیدید, کار و ساخت Queue در php بسیار آسان است و برنامه نویسی را آسان تر می کند.
در مقالات بعدی یک مثال ساده و کاربردی دیگر از کار با صف بندی در PHP و ذخیره آن در دیتابیس را خواهیم دید و همچنین به شما نمایش خواهم داد چطور آیتم های مختلف را پردازش و کار را بین worker های دیگر تقسیم کنید.
همچنین یک پکیج معروف از فریمورک لاراول را به پروژه خود اضافه و کار را بی نهایت ساده و حرفه ای می کنیم.
امیدوارم از آموزش ساخت Queue در PHP نهایت استفاده را برده باشید .
هر سوالی داشتید ، از قسمت نظرات ارسال کنید . سریعا ، پاسخگوی سوالات شما هستیم .
موفق و پیروز باشید.