Menggunakan RabbitMQ dengan MonsterMQ Bagian 4

Dalam artikel sebelumnya, kami menulis sistem logging sederhana. Di mana kami mengirim pesan ke beberapa penerima sekaligus. Dalam artikel ini, kami akan menambahkan fungsi baru yang memungkinkan penerima hanya menerima subset pesan tertentu. Karena itu, kita dapat, misalnya, hanya mengirim pesan penting ke file log, pada saat yang sama menampilkan semua pesan yang dikirim dalam jendela terminal.

Tautan antara antrian dan penukar


Pada artikel sebelumnya, kami belajar cara menghubungkan antrian dengan penukar. Tentang kode ini:

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

Selanjutnya, metode pengikatan dapat menerima kunci rute argumen kedua (kunci routing). Agar tidak membingungkan dengan kunci perutean, yang mengadopsi metode Producer :: publish () sebagai parameter kedua, mari kita menyebutnya kunci penjilidan (kunci penjilidan). Inilah cara kami dapat mengikat exchanger dengan antrian menggunakan kunci bind:

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

Nilai kunci penjilidan tergantung pada jenis penukar. Penukar fanout dari pelajaran sebelumnya mengabaikan nilai ini.

Penukar langsung


Sistem pencatatan kami dari artikel terakhir mengirim semua pesan ke semua penerima.

Mari kita ubah sedikit sehingga memfilter pesan berdasarkan tingkat keparahan. Misalnya, sehingga dia hanya menulis pesan penting ke file log, dan tidak membuang ruang disk pada pesan peringatan dan info.

Penukar fanout tidak memberi kita kesempatan seperti itu.

Tetapi kita dapat menggunakan penukar langsung yang hanya mengirim pesan ke antrian yang kunci pengikatnya cocok dengan kunci perutean pesan yang dikirim (argumen kedua ke metode publish ()). Mekanisme aksi ini diilustrasikan oleh gambar berikut:

gambar
(gambar diambil dari situs resmi RabbitMQ )

Gambar ini menunjukkan exchanger Xtipe langsung dan dua antrian - satu dengan kunci penjilidan oranye dan yang kedua dengan dua kunci pengikat hitam dan hijau .

Dalam instalasi ini, pesan dengan kunci perutean oranye akan dikirim terlebih dahulu, dan pesan dengan kunci perutean hitam atau hijau akan dikirim ke yang kedua. Pesan lain akan dibuang.

Penjilidan berganda


gambar
(gambar diambil dari situs web resmi RabbitMQ )

Sangat dapat diterima untuk mengikat exchanger dengan beberapa antrian dengan satu kunci ikat. Dalam contoh kita, kita dapat menambahkan koneksi antara penukar X dan antrian Q1 menggunakan kunci hitam mengikat . Dalam hal ini, penukar tipe langsung kami akan berperilaku seperti penukar jenis fanout, penukar akan mengirimkan pesan ke semua antrian dengan kunci penjilidan yang cocok. Pesan dengan kunci perutean hitam akan dikirim ke Q1 dan Q2 .

Pesan Rilis


Kami akan menggunakan model yang dijelaskan di atas untuk sistem logging kami. Alih-alih mengirim pesan ke exchanger fanout, kami akan mengirimkannya ke exchanger langsung. Kami akan menunjukkan tingkat keparahan pesan sebagai kunci perutean. Dengan demikian, skrip penerima akan dapat memilih pesan dengan tingkat keparahan yang diinginkan. Tapi pertama-tama, mari kita fokus pada merilis pesan. Seperti biasa, untuk ini pertama-tama kita perlu membuat exchanger.


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

Sekarang kita dapat mengirim pesan:


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

Agar tidak menyulitkan, mari kita asumsikan bahwa tingkat keparahan ($ severity) hanya dapat berupa 'info', 'peringatan', 'kesalahan'.

Berlangganan


Seperti pada bagian sebelumnya, kami akan membuat dua pekerja yang akan mengumumkan antrian dan mengaitkannya dengan exchanger sebagai berikut:


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

Menyatukan semuanya


gambar
(gambar diambil dari situs resmi RabbitMQ )

kode 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);
}

Pekerja kode -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);
}

Kode pekerja-2.php akan berbeda dari pekerja-1.php hanya dalam nama antrian yang terkait dengan penukar dan diteruskan ke metode konsumsi () . Ganti 'antrian-1' dengan 'antrian-2'.

Sekarang, jika Anda ingin pekerja pertama menyimpan pesan tingkat 'kesalahan' dan 'peringatan' ke file, jalankan perintah berikut di terminal:

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

Dan jika Anda ingin pekerja kedua menampilkan semua pesan di jendela terminal, lakukan hal berikut:

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

Dan untuk mengeluarkan pesan kesalahan tulis yang berikut:

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

Itu saja. Di bagian selanjutnya, kita akan belajar cara menerima pesan berdasarkan pola tertentu.

All Articles