Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

RabbitMQ – Akıllı Kuyruk Mimarisi Nasıl Tasarlanır?

Merhaba,

Bir önceki RabbitMQ – Basitçe Kuyruğa Mesaj Gönderme ve Okuma başlıklı yazımda RabbitMQ servisine mesaj gönderme ve gönderilen mesajları okuma eylemlerini temel düzeyde incelemiş bulunmaktayız. Bu içeriğimizde ise kuyruk mimarisini daha da akıllı hale nasıl getirebileceğimizi orta şeker bir gerçek hayat projesi üzerinden konuşacağız.

Akıllı Kuyruk Mimarisi Nedir?

Bir kuyruk mimarisinin akıllı olabilmesi için, (1)edindiği mesajların güvenli bir şekilde tutulup, (2)eşit bir dağılımla tüketilmesi ve tüm bu işlemler neticesinde sunucunun (3)mesajın işlendiğine dair haberdar edilmesi gerekmektedir. İşte böyle bir yapılanma akıllı kuyruk mimarisi olarak nitelendirilebilmektedir.

Bu açıklamadan çıkardığımız sonuç şudur ki bir kuyruk yapısının akıllı olabilmesi için aşağıdaki özellikleri uyguluyor olması gerekmektedir.

  • Mesajların Dayanıklılığı(Message Durability)

    (1)…edindiği mesajların güvenli bir şekilde tutulup…

    RabbitMQ instance’ına gönderilen mesajların güvenliğini sağlayarak olası restart durumlarında kalıcılığı korumak için Publisher ilgili mesajı göndermeden önce mesaj güvenirliliğini sağlamalıdır.

            static void Main(string[] args)
            {
                ConnectionFactory factory = new ConnectionFactory();
                factory.Uri = new Uri("amqp://hkhjerrt:hcqiavAqll6-co4abXnSqUBh_hHifz-Z@hornet.rmq.cloudamqp.com/hkhjerrt");
    
                using (IConnection connection = factory.CreateConnection())
                using (IModel channel = connection.CreateModel())
                {
                    channel.QueueDeclare("iskuyrugu", durable: true, false, false, null);
                    for (int i = 1; i <= 100; i++)
                    {
                        byte[] bytemessage = Encoding.UTF8.GetBytes($"is - {i}");
    
                        IBasicProperties properties = channel.CreateBasicProperties();
                        properties.Persistent = true;
    
                        channel.BasicPublish(exchange: "", routingKey: "iskuyrugu", basicProperties: properties, body: bytemessage);
                    }
                }
            }
    

    Bunun için yukarıdaki kod bloğundaki 9. satırda olduğu gibi ‘durable’ parametresi true olarak ayarlanır ve tanımlanan kuyruk sağlamlaştırılır. Ayriyetten 14 – 15. satırlar arasında bir ‘IBasicProperties’ türünden nesne oluşturulur ve Persistent özelliğine true değeri atanarak RabbitMQ’da fiziksel kayda alınır ve kalıcılığı sağlanır. Böylece mesaj güvenliğide sağlamlaştırılmış olur. 17. satırda ise ‘basicProperties’ parametresine ilgili property verilerek mesajımız güvenli bir şekilde kuyruğa gönderilir.

  • Eşit Dağılım(Fair Dispatch)

    …(2)eşit bir dağılımla tüketilmesi…

    Bir kuyruğu tüketmek için birden fazla consumer olabilir. Böyle bir durumda tüm consumerlara mesajlar eşit dağıtılmalıdır. Aksi taktirde işlemci gücü vs. gibi donanımsal özellikleri daha ağır basan consumerlar kısa zamanda çok mesaj işleyebildikleri için daha yoğun çalışmak zorunda kalabilirler.

    Consumer;

            static void Main(string[] args)
            {
                ConnectionFactory factory = new ConnectionFactory();
                factory.Uri = new Uri("amqp://hkhjerrt:hcqiavAqll6-co4abXnSqUBh_hHifz-Z@hornet.rmq.cloudamqp.com/hkhjerrt");
    
                using (IConnection connection = factory.CreateConnection())
                using (IModel channel = connection.CreateModel())
                {
                    channel.QueueDeclare("iskuyrugu", durable: true, false, false, null);
                    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
    
                    EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
                    channel.BasicConsume("iskuyrugu", false, consumer);
                    consumer.Received += (sender, e) =>
                    {
                        Thread.Sleep(int.Parse(args[0]));
                        Console.WriteLine(Encoding.UTF8.GetString(e.Body) + " alındı");
                        channel.BasicAck(e.DeliveryTag, false);
                    };
                    Console.Read();
                }
            }
    

    Yukarıdaki örnek kod bloğunda bir consumer çalışması yapılmıştır. 10. satıra göz atarsanız eğer ‘BasicQos’ metodu ile port önceliği anlamına gelen QoS servisi ile consumer önceliği eşitlenmekte ve böylece eşit dağılım sağlanmaktadır.

    ‘BasicQos’ metodunun;

    • prefetchSize parametresi : Mesaj boyutunu ifade eder. 0(sıfır) diyerek ilgilenmediğimizi belirtiyoruz.
    • prefetchCount parametresi : Dağıtım adetini ifade eder.
    • global parametresi : true ise, tüm consumerların aynı anda prefetchCount parametresinde belirtilen değer kadar mesaj tüketebileceğini ifade eder. false değeri ise, her bir consumerın bir işleme süresinde diğer consumerlardan bağımsız bir şekilde kaç mesaj alıp işleyeceğini belirtir.
  • Mesajların Alındı Haberi(Message Acknowledgement)

    …(3)mesajın işlendiğine dair haberdar edilmesi…

    Kuyruktaki mesaj consumer tarafından başarıyla işlendikten sonra sunucu bilgilendirilmelidir. Yukarıda “Eşit Dağılım”a verilen örnek kod bloğundaki 18. satırda ‘BasicAck’ fonksiyonu ile bu işlemi gerçekleştirerek kuyruktan mesajın silinmesi sağlanmaktadır.

Test Edelim

Yukarıdaki yaptığımız çalışmaya dikkat ederseniz, publisher her çalıştırıldığında 100 adet mesajı kuyruğa iletmekte ve bunun yanında consumer ise ayağa kaldırılırken gönderilen argümandaki sayısal değer kadar süreci durdurarak işlemektedir. Dolayısıyla bu inşa neticesinde aşağıdaki görselde olduğu gibi anlamlı bir kuyruk mimarisinin neticesiyle karşılaşmaktayız.
RabbitMQ - Akıllı Kuyruk Mimarisi Nasıl Tasarlanır?
Görüldüğü üzere her bir consumer verilen değer kadar saniye aralığında bir mesaj tüketmektedir.

Vee böylece bir RabbitMQ servisini kullanan uygulamada akıllı kuyruk mimarisinin nasıl ve nelere dikkat edilerek tasarlandığını incelemiş ve örneklendirmiş olduk. Vakit ayırıp okuduğunuz için teşekkür ederim 🙂

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek uygulamayı indirmek için buraya tıklayınız.

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. baran dedi ki:

    Hocam merhabalar, BasicConsume ile BasicAck metodlarının farkını ben tam olarak kavrayamadım. İkisi de mesajın okunduğunu bildirmiyor mu uygulamaya? Bazı örneklerer baktığımda 2 si de kullanılıyor aynı anda bazen sadece 1 tanesi. Neye göre dğeişiyor?

  1. 29 Şubat 2020

    […] RabbitMQ – Akıllı Kuyruk Mimarisi Nasıl Tasarlanır? […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*