Rabbitmq da var olan bir kuyruğa Dead Letter Exchange özelliğini arguments olarak eklerken “RabbitMQ of type ‘longstr’ but current is none error” hatası aldım.
Hata mesajı:
PRECONDITION_FAILED – inequivalent arg ‘x-dead-letter-exchange’ for queue ‘my-queue-name’ in vhost ‘/’: received none but current is the value ‘myExchange’ of type ‘longstr’.
Çözüm
Burada bilmemiz gereken ilk önce; arguments olarak belirteceğiniz “x-dead-letter-exchange”, “x-dead-letter-routing-key” parametrelerini hem publisher hem consumer tarafında tanımlama esnasında bildirmek gerekliliğidir.
Aksi takdirde producer ve consumer farklı durumlar set edecek ve bu hataya neden olacaktır.
Maalesef var olan bir kuyruk üzerinde bu şekilde DLX eklemek yani sonradan değişiklik yapmak mümkün olmuyor. Kuyruğun silinip tekrar bu yeni tanımlamalarla birlikte ayağa kaldırmak gerekiyor.
Bir diğer çözüm olarak ise bunu policy ile default olarak set etmek. Bunu kendi sitesinde de belirtiyor. Aşağıda konuya değinip yönlendirme yaptım.
Php Symfony için örnek tanımlama:
producers: upload_picture: connection: default exchange_options: {name: 'upload-exchange', type: direct} queue_options: name: 'upload-picture' durable: true auto_delete: false routing_keys: - 'upload-picture' arguments: x-dead-letter-exchange: ['S', 'upload-exchange'] x-dead-letter-routing-key: ['S', 'upload-picture_error'] consumers: upload_picture: connection: default exchange_options: {name: 'upload-picture', type: direct} queue_options: name: 'upload-picture' type: direct durable: true routing_keys: - 'upload-picture' arguments: x-dead-letter-exchange: ['S', 'upload-exchange'] x-dead-letter-routing-key: ['S', 'upload-picture_error'] callback: upload_picture_service
Yani aynı arguments set edilerek tanımlama yapılmalıdır. Ortak tanımlama olmalıdır.
arguments: x-dead-letter-exchange: ['S', 'upload-exchange'] x-dead-letter-routing-key: ['S', 'upload-picture_error']
Bir diğer çözüm yolu için de kuyruğun silinerek clients tarafından tekrar ayağa kaldırılması. Yukardaki durumu kontrol edip uygularsanız tabi bu duruma gerek kalmayabilir.
https://github.com/jondot/sneakers/issues/121#issuecomment-360039943
https://stackoverflow.com/questions/40146740/change-the-arguments-in-a-rabbitmq-queue
Ayrıca Rabbitmq belirli bir kuyrukta Dead letter exchanges (DLXs) düzenlemek için 2 yol var. Clients yada policy ile server tarafında.
Policies ile belirlendiğinde default olarak özellikleri set ediyor. Ancak clients tarafında bu özelliklere ait parametreler geçilirse Policies de varsayılan ayarlarını ezerek set eder.
Genel ve detaylı bilgi için rabbitmq dökümanına bakabilirsiniz.
https://www.rabbitmq.com/dlx.html
Dead Letter Exchanges belirtmek için arguments kullanılır.
Exchange (Dead Letter Exchange) ve Routing key (Dead Letter Routing Key) belirtilir.
Farklı veya mevcut exchange kullanabilirsiniz.
Symfony için genel bir örnekte paylaşacak olursak:
producers:
send_notify:
connection: default
exchange_options: { name: joker_exchange, type: fanout }
queue_options:
name: notify_queue
arguments:
x-dead-letter-exchange: ['S', 'joker_exchange']
x-dead-letter-routing-key: ['S', 'send_notify_dead_letter_quque']
consumers: send_notify: connection: default exchange_options: { name: joker_exchange, type: fanout } queue_options: name: notify_queue arguments: x-dead-letter-exchange: ['S', 'joker_exchange'] x-dead-letter-routing-key: ['S', 'send_notify_dead_letter_quque'] callback: app.consumer.send_notify send_notify_dead_letter: connection: default exchange_options: { name: joker_exchange, type: fanout } queue_options: { name: send_notify_dead_letter_quque } callback: app.consumer.send_notify_dead_letter
Rabbitmq kod tarafında yapılan değişikliklerin aktif ve kuyrukların setup olması için bu komutu çalıştırın.
app/console rabbitmq:setup-fabric
Symfony için kullanılan pakette arguments için örnek parametre geçme yer alıyor.