RabbitMQ, kendi sitesindeki ifadeye göre en yaygın kullanılan açık kaynak mesaj aracısıdır. Birçok işletim sisteminde ve popüler tüm programlama dillerinde çalışabilir. Faklı uygulamalar arasında asenkron iletişim kurulmasını sağlar. ApacheQPid, ActiveMQ, ZeroMQ gibi farklı alternatif sistemler olduğunu da belirtelim. Temel mantık şu şekildedir: Bir üretici(producer) iletilecek mesajı örneğin postayı kargo firmasına bırakır. Kargo firması yani RabbitMQ ise bu mesajın ilgili alıcı(consumer) tarafından alınmasını sağlar.
RabbitMQ terimler ;
RabbitMQ terimler ;
- Producer: mesajı gönderen uygulamadır
- Queue : Gönderilen mesajlar kuyrukta sıralanır ve alıcıya bu kuyruktan iletilir.
- Consumer: Kuyruktan mesajları okuyan uygulamadır.
Bu yazı kapsamında RabbitMQ nun C++ ve Python ile kullanılmasına dair örnekler paylaşacağım. Bunun için kullanacağımız kütüphaneler SimpleAmqpClient ve pika. SimpleAmqpClient kurulumunu en kolay şekilde (Visual Studio kullanıyorsanız şayet) NuGet Package Manager ile gerçekleştirebilirsiniz. Böylece gerekli boost chrono ve boost system kütüphaneleri de otomatik olarak projenize dahil edilir. Python için pika kurulumu ise, terminalden pip install pika komutu ile kolayca gerçekleştirilir.
İlk olarak Python ile RabbitMQ sunucumuzda mesaj oluşturan üretici(producer) uygulamamızı yazalım.
Python ile RabbitMQ producer
( i=0 baslangıç değeri atanmış bir değişken olsun )
import pika
i=i+1
message = str(i)+". mesaj!"
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='kuyruk1')
# yukarıda aldığımız kanala bir iş gönderiyoruz
channel.basic_publish(exchange='',
routing_key='kuyruk1',
body=message)
print(message + " mesajı sıraya gönderildi.")
connection.close()
Artık her çalıştırmada 1.mesaj, 2.mesaj .... şeklinde mesajları "kuyruk1" isimli kuyruğa gönderecek bir producer.py dosyamız mevcut. Bu dosyayı 5 defa çalıştırdığımızda RabbitMQ sunucusundaki "kuyruk1" isimli kuyrukta 5 mesaj birikecektir. Şimdi ise bu mesajları okuyacak C++ consumer(tüketici) uygulamasını yazalım.
#include<iostream>
#include <SimpleAmqpClient/SimpleAmqpClient.h>
int main()
{
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create("localhost");
std::string consumer_tag = channel->BasicConsume("kuyruk1");
while (1)
{
AmqpClient::Envelope::ptr_t envelope;
channel->BasicConsumeMessage(consumer_tag, envelope, 10); // 10 ms timeout
if (envelope)
{
AmqpClient::BasicMessage::ptr_t mes = envelope->Message();
std::cout << "new mes" << std::endl;
std::string str = mes->Body();
std::cout << str << std::endl<<std::endl;
}
}
// done
return 0;
}
Ekran çıktısı
Böylece producer.py isimli dosyanın gönderdiği mesajları, C++ uygulamamızdan alıp ekranda görüntülemiş olduk.
Şimdi ise RabbitMQ üretici uygulamasını C++ ile, tüketici uygulamasını ise Python ile yazalım.
C++ producer
#include<iostream> #include <SimpleAmqpClient/SimpleAmqpClient.h> int main() { AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create("localhost"); std::string outmes = "message from C++"; AmqpClient::BasicMessage::ptr_t outgoing_message = AmqpClient::BasicMessage::Create(); outgoing_message->Body(outmes); channel->BasicPublish("", "kuyruk1", outgoing_message); return 0; }
Python consumer
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue='kuyruk1') # sıra üzerinde bir mesaj işlendiğinde kullanılacak # geri çağırma fonksiyonu def callback(ch, method, properties, body): print("Bir mesaj geldi => %r" % body) print('Sıraya bir mesaj gelmesi bekleniyor...') # parametreler vererek kanal üzerindeki işleri işlemeye başlıyoruz channel.basic_consume(callback, queue='kuyruk1', no_ack=True) channel.start_consuming()
Ekran çıktısı (C++ uygulamasını 3 defa çalıştırınca)
Bu yazı kapsamında RabbitMQ'nun C++ ve Python ile kullanımına dair örnek uygulamalar gerçekleştirdik. RabbitMQ ile farklı konumlarda çalışan istediğimiz sayıda üretici ve tüketici uygulamaları ekleyerek, farklı diller ile yazılmış uygulamalar arasında asenkron mesaj gönderme/alma işlemlerini kolayca yönetebiliriz.
Merhaba, hem producer hem de consumer'ı C++ olarak yazdım. İki kodu da çalıştırdığımda ikisi de
YanıtlaSilterminate called after throwing an instance of 'AmqpClient::AmqpLibraryException'
what(): a socket error occurred
hatası vermektedir. Nedenini nedir acaba, bir bilginiz var mı? Teşekkür ederim.
Merhaba, RabbitMQ arayüzüne girip "kuyruk1" isminde bir queue oluşturdunuz mu?
SilBu örneklerde fazla detaylara girmedik, Örneğin; kod içerisinde channel->DeclareQueue metodu ile de queue oluşturulabiliyor, ya da exchange oluşturup queue ile bağlantısı yapılabiliyor vs vs.
Ben bunun yerine arayüz ile gerçekleştirdim queue tanılama işini, onu kontrol edebilirsiniz.
Arayüzden queue oluşturduğumda çalıştı, çok teşekkür ederim.
Sil