RabbitMQ yang tidak jelas di Yii2 atau mengapa RabbitMQ menulis ke semua antrian sekaligus


Saya ingin berbagi masalah praktis mengkonfigurasi broker antrian RabbitMQ di Yii2. Saya memperingatkan pembaca bahwa saya tidak memiliki pendapat ahli tentang bekerja dengan broker antrian ini, namun saya benar-benar ingin mengisi celah dalam dokumentasi Yii2 dan memperbaiki hasil dari siksaan saya sendiri. Jadi, jika Anda pernah mengalami masalah bahwa pesan dikirim ke semua antrian yang ada di server antrian, Anda setuju bahwa ini adalah masalah dan tidak mengerti mengapa ini terjadi, maka saya meminta kucing.

Mengapa Anda mungkin menemukan perilaku ini? Misalnya, jika Anda, seperti saya, belum pernah bekerja dengan RabbitMQ sebelumnya, tetapi bekerja misalnya dengan Gearman. Gearman sendiri, sesederhana kereta api ( dipinjam dari karakter Internet yang terkenal dan dihormati ). Anda membuat antrian dengan nama tertentu, letakkan data di sana. Pekerja membaca dari antrian dengan nama yang sama. Semuanya sederhana. Sekarang saatnya menggunakan teknologi mode, tanpa memahami mengapa Anda memilih RabbitMQ. Maka Anda senang bahwa Yii2 memiliki abstraksi siap pakai untuk banyak broker antrian populer. Dokumentasi minim memberi tahu konfigurasi default untuk memulai semuanya:

return [ 'bootstrap' => [ 'queue', // The component registers its own console commands ], 'components' => [ 'queue' => [ 'class' => \yii\queue\amqp_interop\Queue::class, 'port' => 5672, 'user' => 'guest', 'password' => 'guest', 'queueName' => 'queue', 'driver' => yii\queue\amqp_interop\Queue::ENQUEUE_AMQP_LIB, // or 'dsn' => 'amqp://guest:guest@localhost:5672/%2F', // or, same as above 'dsn' => 'amqp:', ], ], ]; 

Tampaknya semuanya sangat sederhana, inilah baris yang sudah dikenal dengan queueName , salin dan tempel, perbaiki, jalankan - berfungsi! Kami membuat antrian untuk komponen lain dari sistem. Kami sejajar dengan apa yang bisa php kami. Berkomitmen, Dorong puas kami menempatkan tugas di QA dan kami pergi untuk membaca habr ( saat istirahat makan siang ).

Di sini, yang paling menarik, QA dalam obrolan mengganggu kami, dan mengatakan bahwa sesuatu yang aneh sedang terjadi. Untuk beberapa alasan, data yang ditulis oleh pekerja (cosumers) digandakan. Apa apa Tidak mungkin seperti itu. Kami pergi untuk memeriksa log. Kita melihat bahwa pesan sedang ditulis ke antrian, dengan mana antrian dipilih dengan benar, hash jobId diterima. Tidak, tidak, kami tidak memiliki kesalahan. Kami menulis QA yang puas, periksa lagi, ini tidak mungkin, kami baik-baik saja.

Secara harfiah setelah setengah jam, kami terganggu lagi, kesalahan itu berulang, dan kemudian pemberitahuan jatuh pada sabun - tugas dipindahkan kembali bekerja. Yah, saya seorang programmer, sekarang kita akan mengetahuinya. RabbitMQ, tidak seperti Gearman, memiliki antarmuka web di mana ada banyak informasi tentang server. Mukjizat ini terlihat seperti ini:



Kami melemparkan beberapa pesan lagi ke antrian, kami melihat di webmord bahwa pesan kami tiba dan diproses oleh pekerja. Sebuah tampilan kasual memperhatikan bahwa ketika kita melempar pesan ke antrian, bagan “Tarif pesan” melompat di semua antrian.



Kami memeriksa konfigurasi seratus kali, membaca kembali dokumentasi Yii yang langka. Kami melakukan semuanya dengan benar. Kami pergi untuk membaca dokumentasi di situs kelinci. Setelah beberapa menit berkeliaran di kegelapan, kami menemukan tutorial . Segera setelah paragraf pertama, kita berkenalan dengan alasan kesalahpahaman kita - Pertukaran. Saya tidak akan mengulang dokumentasi, sangat singkat.

Di RabbitMQ kami tidak menulis pesan ke antrian, kami menulisnya untuk ditukar, semacam proxy yang menerima pesan kami di satu ujung dan berkomunikasi dengan antrian di server di ujung lainnya. Dalam kekuasaannya untuk memutuskan di mana antrian untuk menaruh data kami. Menariknya, tidak ada satu baris pun tentang ini dalam dokumentasi Yii. Pada pandangan pertama, tidak jelas bagaimana cara mengkonfigurasi pertukaran, kami menyelam ke dalam nyali dan di vendor file / yiisoft / yii2-queue / src / drivers / amqp_interop / Queue.php: 176 kami menemukan properti dihargai yang dapat dilihat. Di sini saya harus mengatakan bahwa ada banyak driver untuk RabbitMQ, dalam kasus saya enqueue / amqp-lib digunakan . Kami menetapkan exchangeName , tes, tidak ada perubahan. Ya, kami seperti insinyur Rusia yang asli, pertama kami mencoba, dan kemudian kami pergi membaca dokumentasi dengan serius. Kami membacanya lagi dengan cermat, lalu pergi ke web rabbit dan melihat yang berikut:



Beberapa antrian kami dikaitkan dengan pertukaran yang sama. Bingo! Ini dia alasannya, satu "tapi", saya tidak mengikat mereka. Kami masuk lagi ke usus driver, kami menemukan metode setupBroker baris 392

 $this->context->bind(new AmqpBind($queue, $topic)); 

Ini mengikat yang tidak dikelola.

Jadi, tanpa berpikir lama, kami sampai pada kesimpulan bahwa untuk setiap antrian pertukaran harus dinyatakan, maka koneksi akan benar dan satu pertukaran hanya akan memiliki satu antrian yang terhubung. dengan cara ini kita mendapatkan perilaku Gearman yang serupa. Ngomong-ngomong, dokumentasi menjelaskan secara terperinci mengapa pertukaran dilakukan, dan seperti yang saya mengerti, salah satu alasannya adalah kemampuan untuk menghubungkan beberapa antrian dengan pertukaran. Tetapi saya tidak membuat kasus seperti ini ketika dibutuhkan, kawan-kawan menulis di komentar. Dan tulis, apakah Anda menemui situasi yang dijelaskan di atas atau apakah saya melakukan semuanya dengan salah?

Source: https://habr.com/ru/post/id439080/


All Articles