RabbitMQ of type ‘longstr’ but current is none

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.

Hello world, hello blog! – Tahsin Yüksel

Hep yapmak istediğim geç kalmış blog hayatına merhaba diyebildim sonunda:) Blog hakkında fırsat buldukça yazılım geliştirme, teknoloji, iş hayatı ve kendi hayatımdan değerlendirmeler ve tecrübeler aktarmaya çalışacağım. Özellikle kendimde olan merak ve araştırma dolayı fırsat buldukça burada paylaşımlarda bulunacağım. web programlama, performans, NoSql, big data gibi konularda hem ilgim olduğu için hemde az olan Türkçe kaynaklara destek amaçlı paylaşımlarım olacaktır.

O zaman hello world demiş olalım adettendir 🙂