باستخدام RabbitMQ مع MonsterMQ الجزء 4

في مقال سابق ، كتبنا نظام تسجيل بسيط. أرسلنا رسائل إلى عدة مستلمين في وقت واحد. في هذه المقالة ، سنضيف وظيفة جديدة إليها تسمح للمستلمين بتلقي مجموعة فرعية محددة من الرسائل. ونتيجة لذلك ، يمكننا ، على سبيل المثال ، إرسال رسائل مهمة فقط إلى ملف سجل ، وفي نفس الوقت عرض جميع الرسائل المرسلة في نافذة طرفية.

الروابط بين الطابور والمبادل


في المقالة السابقة ، تعلمنا كيفية توصيل قائمة انتظار بمبادل. حول هذا الرمز:

$producer->queue('queue-1')->bind('logs');

علاوة على ذلك ، يمكن أن تقبل طريقة الربط مفتاح توجيه وسيطة ثاني (مفتاح التوجيه). لكي لا نخلط بينه وبين مفتاح التوجيه ، الذي يتبنى طريقة Producer :: Publish () كمعلمة ثانية ، فلنطلق عليه مفتاح ربط (مفتاح ربط). إليك كيفية ربط المبادل بقائمة الانتظار باستخدام مفتاح الربط:

$producer->queue('queue-2')->bind('logs', 'binding-key');

تعتمد قيمة مفتاح الربط على نوع المبادل. يتجاهل مبادل Fanout من الدرس السابق هذه القيمة.

مبادل مباشر


يرسل نظام التسجيل الخاص بنا من المقالة الأخيرة جميع الرسائل إلى جميع المستلمين.

دعنا نغيره قليلاً حتى يقوم بتصفية الرسائل بناءً على مستوى الخطورة. على سبيل المثال ، بحيث تكتب الرسائل المهمة فقط في ملف السجل ، ولا تضيع مساحة القرص على رسائل التحذير والمعلومات.

مبادل Fanout لا يعطينا مثل هذه الفرصة.

ولكن يمكننا استخدام مبادل مباشر يرسل الرسائل فقط إلى قوائم الانتظار التي يتطابق مفتاح ربطها مع مفتاح التوجيه للرسالة المرسلة (الوسيطة الثانية لطريقة النشر ()). يتم توضيح آلية العمل هذه من خلال الصورة التالية:

صورة
(صورة مأخوذة من الموقع الرسمي لـ RabbitMQ )

توضح هذه الصورة المبادل Xمن نوع مباشر واثنين من الطوابير - واحد مع البرتقال مفتاح الربط والثانية مع اثنين السوداء و الخضراء مفاتيح ملزمة .

في هذا التثبيت ، سيتم إرسال الرسائل ذات مفتاح التوجيه البرتقالي أولاً ، وسيتم إرسال الرسائل التي تحتوي على مفاتيح التوجيه السوداء أو الخضراء إلى الثانية. سيتم تجاهل أي رسائل أخرى.

ملزمة متعددة


صورة
(صورة مأخوذة من موقع RabbitMQ الرسمي ) من

المقبول تمامًا ربط المبادل بعدة طوابير بمفتاح ربط واحد. في مثالنا ، يمكننا إضافة اتصال بين المبادل X وقائمة انتظار Q1 باستخدام مفتاح الربط الأسود . في هذه الحالة ، سيتصرف مبادل النوع المباشر لدينا مثل مبادل نوع Fanout ، سيرسل رسائل إلى جميع قوائم الانتظار باستخدام مفتاح الربط المطابق. سيتم تسليم رسالة بمفتاح التوجيه الأسود إلى كل من Q1 و Q2 .

إصدار الرسالة


سنستخدم النموذج الموضح أعلاه لنظام التسجيل لدينا. بدلاً من إرسال رسائل إلى مبادل Fanout ، سنرسلها إلى المبادل المباشر. سنشير إلى مستوى خطورة الرسالة كمفتاح توجيه. وبالتالي ، سيتمكن البرنامج النصي للمستلم من تحديد رسائل مستوى الخطورة المطلوب. لكن أولاً ، دعنا نركز على نشر الرسائل. كما هو الحال دائمًا ، لهذا نحتاج أولاً إلى إنشاء مبادل.


$producer->newDirectExchange('my-logs');

الآن يمكننا إرسال رسائل:


$producer->newDirectExchange('my-logs');
$producer->publish($message, $severity, 'my-logs');

لكي لا نعقد الأمور ، لنفترض أن مستوى الخطورة (خطورة $) يمكن أن يكون فقط "معلومات" ، "تحذير" ، "خطأ".

اشتراك


كما في الجزء السابق ، سننشئ عاملين سيعلنان عن الطوابير وربطهما بالمبادل على النحو التالي:


// Worker 1
foreach ($severities as $severity) {
   $consumer->queue('queue-1')->bind('my-logs', $severity);
}

ضع كل شيء معا


صورة
(الصورة مأخوذة من موقع RabbitMQ الرسمي )

كود send.php :


try {
   $producer = \MonsterMQ\Client\Producer();

   $producer->connect('127.0.0.1', 5672);
   $producer->logIn('guest', 'guest');

   $producer->newDirectExchange('my-logs');

   $severity = isset($argv[1]) && !empty($argv[1]) ? $argv[1] : 'info';

   $message = implode(' ', array_slice($argv, 2));
   $message = empty($message) ? "Hello World!" : $message;

   $producer->publish($message, $severity, 'my-logs');

   echo "\n Sent {$message} \n";
} catch(\Exception $e) {
   var_dump($e);
}

عامل الرمز 1.php :


try {
   $consumer = \MonsterMQ\Client\Consumer();

   $consumer->connect('127.0.0.1', 5672);
   $consumer->logIn('guest', 'guest');

   $producer->queue('queue-1')->setExclusive()->declare();

   $severities = array_slice($argv, 1);
   if (empty($severities)) {
      file_put_contents('php://stderr', "Usage: $argv[0] [info] [warning] [error]\n");
      exit(1);
   }

   foreach ($severities as $severity) {
      $producer->queue('queue-1')->bind('my-logs', $severity);
   }

   $consumer->consume('queue-1');

  echo " \n Waiting for logs. To exit press CTRL+C\n";

   $consumer->wait(function ($message, $channelNumber) use ($consumer){
      echo "\n $message \n";
   });
} catch(\Exception $e) {
   var_dump($e);
}

في كود العمال و2.php سوف تختلف من العمال و1.php فقط في اسم قائمة انتظار المرتبطة المبادلات وتمريرها إلى تستهلك () طريقة . استبدل "queue-1" بـ "queue-2".

الآن ، إذا كنت تريد أن يقوم العامل الأول بحفظ رسائل من مستوى "الخطأ" و "التحذير" في ملف ، قم بتشغيل الأمر التالي في المحطة:

php worker-1.php warning error > logs_from_rabbit.log

وإذا كنت تريد أن يعرض العامل الثاني جميع الرسائل في نافذة الوحدة الطرفية ، فقم بما يلي:

php worker-2.php info warning error
# => Waiting for logs. To exit press CTRL+C

ولإصدار رسالة خطأ اكتب ما يلي:

php send.php error "Run. Run. Or it will explode."

هذا كل شئ. في الجزء التالي ، سوف نتعلم كيفية استقبال الرسائل بناءً على نمط معين.

All Articles