{"id":30426,"date":"2025-09-27T17:41:52","date_gmt":"2025-09-27T14:41:52","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=30426"},"modified":"2025-09-27T17:41:52","modified_gmt":"2025-09-27T14:41:52","slug":"rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/","title":{"rendered":"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi"},"content":{"rendered":"<p><body><\/p>\n<h2>RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi<\/h2>\n<h2>Giri\u015f: Mesaj Kuyruklar\u0131 ve Da\u011f\u0131t\u0131k Sistemler<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn modern yaz\u0131l\u0131m mimarilerinde, uygulamalar genellikle ba\u011f\u0131ms\u0131z servislerden olu\u015fan da\u011f\u0131t\u0131k sistemler \u015feklinde tasarlan\u0131r. Bu servislerin birbiriyle g\u00fcvenli, esnek ve \u00f6l\u00e7eklenebilir bir \u015fekilde ileti\u015fim kurmas\u0131 kritik \u00f6neme sahiptir. Monolitik uygulamalar\u0131n yerini alan mikroservis mimarileri, bu ileti\u015fim ihtiyac\u0131n\u0131 daha da belirgin hale getirmi\u015ftir. \u0130\u015fte tam bu noktada mesaj kuyruklar\u0131 (message queues) devreye girer.<\/p>\n<p>Mesaj kuyruklar\u0131, farkl\u0131 uygulama bile\u015fenlerinin asenkron olarak ileti\u015fim kurmas\u0131n\u0131 sa\u011flayan bir arac\u0131 (broker) g\u00f6revi g\u00f6r\u00fcr. Bir bile\u015fen (\u00fcretici\/producer), mesaj\u0131 kuyru\u011fa b\u0131rak\u0131r ve di\u011fer bile\u015fenler (t\u00fcketici\/consumer) bu mesajlar\u0131 kuyruktan al\u0131r. Bu modelin en b\u00fcy\u00fck avantajlar\u0131 aras\u0131nda sistem bile\u015fenleri aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 azaltmas\u0131, \u00f6l\u00e7eklenebilirli\u011fi art\u0131rmas\u0131, y\u00fck dengelemesi sa\u011flamas\u0131 ve sistemin genel g\u00fcvenilirli\u011fini y\u00fckseltmesi yer al\u0131r. \u00d6rne\u011fin, bir web uygulamas\u0131 bir kullan\u0131c\u0131n\u0131n foto\u011fraf\u0131n\u0131 i\u015flemek gibi zaman al\u0131c\u0131 bir g\u00f6revi direkt olarak yerine getirmek yerine, bu g\u00f6revi bir mesaj kuyru\u011funa b\u0131rakabilir. Arka plandaki bir i\u015fleyici (worker) servisi bu mesaj\u0131 kuyruktan al\u0131p foto\u011fraf\u0131 i\u015flerken, web uygulamas\u0131 kullan\u0131c\u0131ya an\u0131nda yan\u0131t verebilir.<\/p>\n<h3>Mesaj Kuyruklar\u0131 Neden \u00d6nemli?<\/h3>\n<p>*   <strong>Ba\u011f\u0131ms\u0131zl\u0131k (Decoupling):<\/strong> \u00dcreticiler ve t\u00fcketiciler birbirlerinin varl\u0131\u011f\u0131ndan haberdar olmak zorunda de\u011fildir. Sadece belirli bir mesaj format\u0131n\u0131 ve kuyru\u011fu bilmeleri yeterlidir. Bu, sistemin farkl\u0131 par\u00e7alar\u0131n\u0131n ba\u011f\u0131ms\u0131z olarak geli\u015ftirilmesine, da\u011f\u0131t\u0131lmas\u0131na ve \u00f6l\u00e7eklenmesine olanak tan\u0131r.<br \/>\n*   <strong>Asenkron \u0130leti\u015fim:<\/strong> Mesajlar an\u0131nda i\u015flenmek zorunda de\u011fildir. \u00dcretici mesaj\u0131 b\u0131rak\u0131r ve kendi i\u015fine devam ederken, t\u00fcketici mesaj\u0131 uygun oldu\u011funda i\u015fler. Bu, \u00f6zellikle yava\u015f veya yo\u011fun i\u015flemler i\u00e7in sistem yan\u0131t s\u00fcrelerini iyile\u015ftirir.<br \/>\n*   <strong>Y\u00fck Dengeleme ve \u00d6l\u00e7eklenebilirlik:<\/strong> Birden fazla t\u00fcketici ayn\u0131 kuyruktan mesaj alarak i\u015f y\u00fck\u00fcn\u00fc payla\u015fabilir. Yeni bir t\u00fcketici eklemek veya mevcut t\u00fcketicileri kald\u0131rmak, sistemin genel performans\u0131n\u0131 etkilemeden kolayca yap\u0131labilir.<br \/>\n*   <strong>G\u00fcvenilirlik ve Dayan\u0131kl\u0131l\u0131k:<\/strong> Mesaj kuyruklar\u0131, mesajlar\u0131n i\u015flenene kadar kal\u0131c\u0131 olarak depolanmas\u0131n\u0131 sa\u011flayabilir. Bir t\u00fcketici \u00e7\u00f6kerse veya ba\u011flant\u0131s\u0131 kesilirse, mesaj kaybolmaz ve ba\u015fka bir t\u00fcketici taraf\u0131ndan i\u015flenebilir.<br \/>\n*   <strong>Hata Tolerans\u0131:<\/strong> Bir bile\u015fen ar\u0131zaland\u0131\u011f\u0131nda, di\u011fer bile\u015fenler \u00e7al\u0131\u015fmaya devam edebilir. Ar\u0131zalanan bile\u015fen tekrar aya\u011fa kalkt\u0131\u011f\u0131nda, biriken mesajlar\u0131 i\u015flemeye ba\u015flayabilir.<\/p>\n<h3>RabbitMQ&#8217;ya K\u0131sa Bir Bak\u0131\u015f<\/h3>\n<p>RabbitMQ, bu alandaki en pop\u00fcler ve g\u00fc\u00e7l\u00fc mesaj brokerlar\u0131ndan biridir. Advanced Message Queuing Protocol (AMQP) standard\u0131n\u0131 uygulayan a\u00e7\u0131k kaynakl\u0131 bir mesaj kuyru\u011fu yaz\u0131l\u0131m\u0131d\u0131r. Erlang ile yaz\u0131lm\u0131\u015f olup, y\u00fcksek performans, g\u00fcvenilirlik ve esneklik sunar. \u00c7e\u015fitli programlama dilleri i\u00e7in istemci k\u00fct\u00fcphaneleri (client libraries) bulunur ve bu da onu farkl\u0131 teknolojilerle entegrasyon i\u00e7in ideal bir se\u00e7im haline getirir.<\/p>\n<p>Bu makalede, RabbitMQ&#8217;nun temel prensiplerini ve Python i\u00e7in geli\u015ftirilmi\u015f Puka k\u00fct\u00fcphanesini kullanarak birden fazla t\u00fcketiciye mesajlar\u0131n nas\u0131l iletilece\u011fini detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Puka, Twisted \u00e7at\u0131s\u0131 ile entegre olabilen asenkron bir RabbitMQ istemcisidir ve \u00f6zellikle y\u00fcksek e\u015fzamanl\u0131l\u0131k gerektiren uygulamalarda tercih edilebilir.<\/p>\n<h2>RabbitMQ Temelleri: Kavramlar ve Kurulum<\/h2>\n<p>RabbitMQ&#8217;yu etkili bir \u015fekilde kullanabilmek i\u00e7in baz\u0131 temel kavramlar\u0131 anlamak \u00f6nemlidir. Bu kavramlar, mesajlar\u0131n nas\u0131l \u00fcretildi\u011fi, y\u00f6nlendirildi\u011fi ve t\u00fcketildi\u011fi konusunda bir \u00e7er\u00e7eve sunar.<\/p>\n<h3>Temel RabbitMQ Kavramlar\u0131<\/h3>\n<p>*   <\/p>\n<h4>Producer (\u00dcretici)<\/h4>\n<p>    Mesajlar\u0131 olu\u015fturan ve RabbitMQ&#8217;ya g\u00f6nderen uygulamad\u0131r. \u00dcretici, mesajlar\u0131 do\u011frudan kuyruklara g\u00f6ndermez; bunun yerine bir Exchange&#8217;e g\u00f6nderir.<\/p>\n<p>*   <\/p>\n<h4>Consumer (T\u00fcketici)<\/h4>\n<p>    Mesajlar\u0131 RabbitMQ&#8217;dan alan ve i\u015fleyen uygulamad\u0131r. T\u00fcketiciler, belirli bir kuyru\u011fa abone olur ve oradan mesajlar\u0131 \u00e7eker.<\/p>\n<p>*   <\/p>\n<h4>Queue (Kuyruk)<\/h4>\n<p>    Mesajlar\u0131n depoland\u0131\u011f\u0131 yerdir. T\u00fcketiciler, mesajlar\u0131 bu kuyruklardan al\u0131r. Kuyruklar, isimleri ile tan\u0131mlan\u0131r ve mesajlar\u0131 FIFO (First-In, First-Out) prensibiyle tutar.<\/p>\n<p>*   <\/p>\n<h4>Exchange (De\u011fi\u015ftirici)<\/h4>\n<p>    \u00dcreticiden gelen mesajlar\u0131 al\u0131r ve belirli kurallara g\u00f6re bir veya daha fazla kuyru\u011fa y\u00f6nlendirir. RabbitMQ&#8217;da farkl\u0131 Exchange t\u00fcrleri bulunur:<br \/>\n    *   <strong>Direct Exchange:<\/strong> Mesaj\u0131, mesaj\u0131n <code>routing key<\/code>&#8216;i ile kuyru\u011fun <code>binding key<\/code>&#8216;i tam olarak e\u015fle\u015fen kuyruklara y\u00f6nlendirir.<br \/>\n    *   <strong>Fanout Exchange:<\/strong> Mesaj\u0131, kendisine ba\u011fl\u0131 olan t\u00fcm kuyruklara y\u00f6nlendirir. Yay\u0131nlama (publish\/subscribe) senaryolar\u0131 i\u00e7in idealdir.<br \/>\n    *   <strong>Topic Exchange:<\/strong> Mesaj\u0131, mesaj\u0131n <code>routing key<\/code>&#8216;i ile kuyru\u011fun <code>binding key<\/code>&#8216;i belirli bir kal\u0131ba (pattern) g\u00f6re e\u015fle\u015fen kuyruklara y\u00f6nlendirir. Daha esnek y\u00f6nlendirme sa\u011flar.<br \/>\n    *   <strong>Headers Exchange:<\/strong> Mesaj\u0131, mesaj\u0131n ba\u015fl\u0131k (header) \u00f6zelliklerine g\u00f6re y\u00f6nlendirir. Daha az kullan\u0131l\u0131r.<\/p>\n<p>*   <\/p>\n<h4>Binding (Ba\u011flama)<\/h4>\n<p>    Bir Exchange ile bir Kuyruk aras\u0131ndaki ba\u011flant\u0131d\u0131r. Binding, Exchange&#8217;e hangi kuyruklara mesaj g\u00f6nderece\u011fini s\u00f6yler. Binding&#8217;ler genellikle bir <code>binding key<\/code> ile tan\u0131mlan\u0131r.<\/p>\n<h3>RabbitMQ Kurulumu<\/h3>\n<p>RabbitMQ&#8217;yu kullanmaya ba\u015flamadan \u00f6nce onu bir sunucuya kurman\u0131z gerekir. En yayg\u0131n kurulum y\u00f6ntemleri \u015funlard\u0131r:<\/p>\n<p>*   <strong>Docker ile Kurulum:<\/strong> En h\u0131zl\u0131 ve pratik y\u00f6ntemlerden biridir.<\/p>\n<pre><code class=\"language-bash\">docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management<\/code><\/pre>\n<p>    Bu komut, RabbitMQ&#8217;yu y\u00f6netim aray\u00fcz\u00fc ile birlikte bir Docker konteynerinde ba\u015flat\u0131r. <code>5672<\/code> portu AMQP ba\u011flant\u0131lar\u0131 i\u00e7in, <code>15672<\/code> portu ise y\u00f6netim aray\u00fcz\u00fc i\u00e7in kullan\u0131l\u0131r.<\/p>\n<p>*   <strong>\u0130\u015fletim Sistemi \u00dczerine Kurulum:<\/strong> \u0130\u015fletim sisteminize (Ubuntu, CentOS, Windows vb.) \u00f6zg\u00fc paket y\u00f6neticileri veya kurulum dosyalar\u0131 kullan\u0131larak kurulabilir. \u00d6rne\u011fin, Ubuntu&#8217;da:<\/p>\n<pre><code class=\"language-bash\">sudo apt update\n    sudo apt install rabbitmq-server<\/code><\/pre>\n<p>    Kurulumdan sonra RabbitMQ servisini ba\u015flatman\u0131z gerekebilir: <code>sudo systemctl start rabbitmq-server<\/code>.<\/p>\n<h3>RabbitMQ Y\u00f6netim Aray\u00fcz\u00fc<\/h3>\n<p>RabbitMQ ile birlikte gelen y\u00f6netim aray\u00fcz\u00fc (Management UI), kuyruklar\u0131, exchange&#8217;leri, ba\u011flant\u0131lar\u0131 ve mesajlar\u0131 izlemek i\u00e7in \u00e7ok de\u011ferli bir ara\u00e7t\u0131r. Docker ile kurdu\u011funuzda <code>http:\/\/localhost:15672<\/code> adresinden eri\u015febilirsiniz (varsay\u0131lan kullan\u0131c\u0131 ad\u0131: <code>guest<\/code>, \u015fifre: <code>guest<\/code>). Bu aray\u00fcz, sistemin durumunu anlamak ve sorun gidermek i\u00e7in olduk\u00e7a faydal\u0131d\u0131r.<\/p>\n<h2>Python ve Puka: Neden Puka?<\/h2>\n<p>Python i\u00e7in RabbitMQ ile etkile\u015fim kurmak \u00fczere birka\u00e7 farkl\u0131 istemci k\u00fct\u00fcphanesi bulunmaktad\u0131r. En bilinenleri Pika, aio-pika ve Puka&#8217;d\u0131r. Bu makale, \u00f6zellikle Puka k\u00fct\u00fcphanesine odaklanmaktad\u0131r.<\/p>\n<h3>Puka Nedir ve Avantajlar\u0131 Nelerdir?<\/h3>\n<p>Puka, Python i\u00e7in Twisted \u00e7at\u0131s\u0131 ile uyumlu, asenkron bir AMQP istemcisidir. Asenkron yap\u0131s\u0131 sayesinde, I\/O i\u015flemlerini beklerken uygulaman\u0131n bloke olmamas\u0131n\u0131 sa\u011flar. Bu, \u00f6zellikle ayn\u0131 anda birden fazla ba\u011flant\u0131y\u0131 y\u00f6netmesi gereken veya d\u00fc\u015f\u00fck gecikmeli, y\u00fcksek e\u015fzamanl\u0131l\u0131k gerektiren uygulamalar i\u00e7in b\u00fcy\u00fck bir avantajd\u0131r.<\/p>\n<p>Puka&#8217;n\u0131n temel avantajlar\u0131 \u015funlard\u0131r:<br \/>\n*   <strong>Asenkron Yap\u0131:<\/strong> Twisted event loop \u00fczerine in\u015fa edildi\u011fi i\u00e7in, a\u011f i\u015flemlerini bloke etmeden ayn\u0131 anda bir\u00e7ok mesaj\u0131 g\u00f6nderebilir veya alabilir.<br \/>\n*   <strong>Twisted Entegrasyonu:<\/strong> E\u011fer uygulaman\u0131z zaten Twisted kullan\u0131yorsa, Puka do\u011fal bir se\u00e7im olacakt\u0131r. Twisted&#8217;\u0131n g\u00fc\u00e7l\u00fc a\u011f ve e\u015fzamanl\u0131l\u0131k yeteneklerinden faydalan\u0131r.<br \/>\n*   <strong>Basit API:<\/strong> Puka, AMQP protokol\u00fcn\u00fcn karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 soyutlayarak, nispeten basit ve kullan\u0131m\u0131 kolay bir API sunar.<br \/>\n*   <strong>Geri \u00c7a\u011fr\u0131 Tabanl\u0131 Model:<\/strong> Asenkron i\u015flemleri y\u00f6netmek i\u00e7in geri \u00e7a\u011fr\u0131 (callback) fonksiyonlar\u0131n\u0131 kullan\u0131r.<\/p>\n<p>Ancak, Puka&#8217;n\u0131n dezavantaj\u0131, Pika veya aio-pika kadar aktif olarak geli\u015ftirilmemesi ve topluluk deste\u011finin daha az olmas\u0131d\u0131r. Yine de, belirli senaryolarda ve Twisted tabanl\u0131 projelerde hala ge\u00e7erli bir se\u00e7enek olabilir.<\/p>\n<h3>Puka Kurulumu<\/h3>\n<p>Puka&#8217;y\u0131 Python projenize dahil etmek olduk\u00e7a basittir. <code>pip<\/code> paket y\u00f6neticisini kullanarak kurabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">pip install puka<\/code><\/pre>\n<p>Bu komut, Puka k\u00fct\u00fcphanesini ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 sisteminize y\u00fckleyecektir.<\/p>\n<h2>Puka ile RabbitMQ Ba\u011flant\u0131s\u0131 ve Temel \u0130\u015flemler<\/h2>\n<p>\u015eimdi, Puka kullanarak RabbitMQ ile nas\u0131l ba\u011flant\u0131 kurulaca\u011f\u0131n\u0131 ve temel mesajla\u015fma i\u015flemlerinin nas\u0131l ger\u00e7ekle\u015ftirilece\u011fini ad\u0131m ad\u0131m inceleyelim.<\/p>\n<h3>Puka \u0130stemcisi ile Ba\u011flant\u0131 Kurma<\/h3>\n<p>Puka ile RabbitMQ&#8217;ya ba\u011flanmak i\u00e7in <code>puka.Client<\/code> s\u0131n\u0131f\u0131n\u0131 kullan\u0131r\u0131z. Ba\u011flant\u0131 asenkron oldu\u011fu i\u00e7in, <code>connect()<\/code> metodunun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc <code>defer.Deferred<\/code> nesnesini dinlememiz gerekir.<\/p>\n<pre><code class=\"language-python\">import puka\nfrom twisted.internet import reactor, defer\n\n<h2>RabbitMQ ba\u011flant\u0131 URL'si<\/h2>\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\n\n@defer.inlineCallbacks\ndef connect_to_rabbitmq():\n    client = puka.Client(RABBITMQ_URL)\n    print(\"RabbitMQ'ya ba\u011flan\u0131l\u0131yor...\")\n    try:\n        yield client.connect()\n        print(\"RabbitMQ'ya ba\u015far\u0131yla ba\u011fland\u0131.\")\n        # Di\u011fer i\u015flemleri burada yapabiliriz\n        yield client.close()\n        print(\"Ba\u011flant\u0131 kapat\u0131ld\u0131.\")\n    except Exception as e:\n        print(f\"Ba\u011flant\u0131 hatas\u0131: {e}\")\n    finally:\n        reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(connect_to_rabbitmq)\n    reactor.run()<\/code><\/pre>\n<p>Bu kod par\u00e7as\u0131, Twisted <code>reactor<\/code>&#8216;\u0131n\u0131 kullanarak RabbitMQ&#8217;ya ba\u011flan\u0131r ve ba\u011flant\u0131 ba\u015far\u0131l\u0131 olursa bir mesaj yazd\u0131r\u0131r. <code>defer.inlineCallbacks<\/code> dekorat\u00f6r\u00fc, asenkron kodlar\u0131 senkron gibi yazmam\u0131z\u0131 sa\u011flar (<code>yield<\/code> anahtar kelimesi ile).<\/p>\n<h3>Kuyruk ve Exchange Bildirimi<\/h3>\n<p>Mesaj g\u00f6ndermeden veya almadan \u00f6nce, kullanaca\u011f\u0131m\u0131z kuyruklar\u0131 ve exchange&#8217;leri RabbitMQ&#8217;ya bildirmemiz (declare) gerekir. Bu i\u015flem, e\u011fer mevcut de\u011fillerse onlar\u0131 olu\u015fturur.<\/p>\n<pre><code class=\"language-python\">import puka\nfrom twisted.internet import reactor, defer\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\n\n@defer.inlineCallbacks\ndef declare_entities():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    # Exchange bildirimi (fanout t\u00fcr\u00fcnde)\n    exchange_name = 'my_fanout_exchange'\n    yield client.exchange_declare(exchange=exchange_name, type='fanout')\n    print(f\"'{exchange_name}' exchange bildirildi.\")\n\n    # Kuyruk bildirimi\n    queue_name = 'my_queue'\n    yield client.queue_declare(queue=queue_name)\n    print(f\"'{queue_name}' kuyru\u011fu bildirildi.\")\n\n    yield client.close()\n    reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(declare_entities)\n    reactor.run()<\/code><\/pre>\n<p><code>exchange_declare<\/code> ve <code>queue_declare<\/code> metodlar\u0131, ilgili varl\u0131klar\u0131 RabbitMQ \u00fczerinde tan\u0131mlar. <code>type='fanout'<\/code> parametresi, exchange&#8217;in t\u00fcr\u00fcn\u00fc belirtir.<\/p>\n<h3>Binding Olu\u015fturma<\/h3>\n<p>Bir Exchange&#8217;den bir kuyru\u011fa mesajlar\u0131n y\u00f6nlendirilmesi i\u00e7in bir binding olu\u015fturulmal\u0131d\u0131r.<\/p>\n<pre><code class=\"language-python\">import puka\nfrom twisted.internet import reactor, defer\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\n\n@defer.inlineCallbacks\ndef create_binding():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    exchange_name = 'my_direct_exchange'\n    queue_name = 'my_direct_queue'\n    routing_key = 'info' # Direct exchange i\u00e7in routing key\n\n    # Exchange ve kuyruk bildirimleri (gerekirse)\n    yield client.exchange_declare(exchange=exchange_name, type='direct')\n    yield client.queue_declare(queue=queue_name)\n\n    # Binding olu\u015fturma\n    yield client.queue_bind(exchange=exchange_name, queue=queue_name, routing_key=routing_key)\n    print(f\"'{exchange_name}' exchange ile '{queue_name}' kuyru\u011fu '{routing_key}' anahtar\u0131yla ba\u011fland\u0131.\")\n\n    yield client.close()\n    reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(create_binding)\n    reactor.run()<\/code><\/pre>\n<p><code>queue_bind<\/code> metodu, bir exchange&#8217;i bir kuyru\u011fa ba\u011flar. <code>routing_key<\/code> parametresi, <code>direct<\/code> ve <code>topic<\/code> exchange&#8217;ler i\u00e7in mesaj y\u00f6nlendirmede kullan\u0131l\u0131r. <code>fanout<\/code> exchange&#8217;lerde <code>routing_key<\/code> genellikle bo\u015f b\u0131rak\u0131l\u0131r veya g\u00f6z ard\u0131 edilir.<\/p>\n<h3>Mesaj G\u00f6nderme (Producer)<\/h3>\n<p>Mesaj g\u00f6ndermek i\u00e7in <code>basic_publish<\/code> metodunu kullan\u0131r\u0131z.<\/p>\n<pre><code class=\"language-python\">import puka\nfrom twisted.internet import reactor, defer\nimport time\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\n\n@defer.inlineCallbacks\ndef send_message():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Producer: Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    exchange_name = 'my_fanout_exchange'\n    # Fanout exchange'e mesaj g\u00f6nderirken routing_key bo\u015f b\u0131rak\u0131l\u0131r\n    yield client.exchange_declare(exchange=exchange_name, type='fanout')\n    print(f\"Producer: '{exchange_name}' exchange bildirildi.\")\n\n    message_count = 5\n    for i in range(message_count):\n        message_body = f\"Hello from producer! Message {i+1}\"\n        yield client.basic_publish(exchange=exchange_name, routing_key='', body=message_body)\n        print(f\"Producer: Mesaj g\u00f6nderildi: '{message_body}'\")\n        time.sleep(0.1) # K\u00fc\u00e7\u00fck bir gecikme\n\n    print(f\"Producer: Toplam {message_count} mesaj g\u00f6nderildi.\")\n    yield client.close()\n    reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(send_message)\n    reactor.run()<\/code><\/pre>\n<p><code>basic_publish<\/code> metoduna <code>exchange<\/code> ad\u0131, <code>routing_key<\/code> (e\u011fer varsa) ve mesaj\u0131n <code>body<\/code>&#8216;si verilir.<\/p>\n<h3>Mesaj Alma (Consumer) ve Onaylama (Acknowledgement)<\/h3>\n<p>T\u00fcketiciler, <code>basic_consume<\/code> metodu ile bir kuyruktan mesajlar\u0131 almaya ba\u015flar. Mesaj i\u015flendikten sonra, RabbitMQ&#8217;ya mesaj\u0131n ba\u015far\u0131yla al\u0131nd\u0131\u011f\u0131n\u0131 ve i\u015flendi\u011fini bildirmek i\u00e7in bir onay (acknowledgement &#8211; ACK) g\u00f6ndermek \u00f6nemlidir. Bu, mesaj\u0131n kaybolmamas\u0131n\u0131 sa\u011flar.<\/p>\n<pre><code class=\"language-python\">import puka\nfrom twisted.internet import reactor, defer\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\n\n@defer.inlineCallbacks\ndef receive_messages():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Consumer: Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    exchange_name = 'my_fanout_exchange'\n    # Ge\u00e7ici, \u00f6zel ve otomatik silinen bir kuyruk olu\u015ftural\u0131m\n    result = yield client.queue_declare(exclusive=True, auto_delete=True)\n    queue_name = result['queue']\n    print(f\"Consumer: Ge\u00e7ici kuyruk olu\u015fturuldu: '{queue_name}'\")\n\n    yield client.exchange_declare(exchange=exchange_name, type='fanout')\n    yield client.queue_bind(exchange=exchange_name, queue=queue_name, routing_key='')\n    print(f\"Consumer: '{exchange_name}' exchange ile '{queue_name}' kuyru\u011fu ba\u011fland\u0131.\")\n\n    # Mesajlar\u0131 t\u00fcketmeye ba\u015fla\n    consume_result = yield client.basic_consume(queue=queue_name, no_ack=False)\n    print(\"Consumer: Mesajlar bekleniyor. \u00c7\u0131kmak i\u00e7in Ctrl+C.\")\n\n    try:\n        while True:\n            message = yield consume_result.wait()\n            print(f\"Consumer: Mesaj al\u0131nd\u0131: '{message['body']}' (Delivery Tag: {message['delivery_tag']})\")\n            # Mesaj\u0131 i\u015fleme sim\u00fclasyonu\n            # time.sleep(1)\n            \n            # Mesaj\u0131 onaylama\n            yield client.basic_ack(message['delivery_tag'])\n            print(f\"Consumer: Mesaj onayland\u0131: {message['delivery_tag']}\")\n    except KeyboardInterrupt:\n        print(\"Consumer: Kapat\u0131l\u0131yor...\")\n    finally:\n        yield client.close()\n        reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(receive_messages)\n    reactor.run()<\/code><\/pre>\n<p><code>queue_declare(exclusive=True, auto_delete=True)<\/code> ile olu\u015fturulan kuyruk, sadece bu ba\u011flant\u0131 taraf\u0131ndan kullan\u0131labilir (<code>exclusive<\/code>) ve ba\u011flant\u0131 kapand\u0131\u011f\u0131nda otomatik olarak silinir (<code>auto_delete<\/code>). Bu, \u00f6zellikle <code>fanout<\/code> exchange ile yay\u0131nlama senaryolar\u0131nda her t\u00fcketicinin kendi ge\u00e7ici kuyru\u011funa sahip olmas\u0131 istendi\u011finde kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<p><code>basic_consume<\/code> metoduna <code>no_ack=False<\/code> parametresi verilerek manuel onaylama etkinle\u015ftirilir. Mesaj i\u015flendikten sonra <code>client.basic_ack(message['delivery_tag'])<\/code> ile RabbitMQ&#8217;ya mesaj\u0131n i\u015flendi\u011fi bildirilir. E\u011fer bir mesaj onaylanmazsa ve t\u00fcketici ba\u011flant\u0131s\u0131 kesilirse, RabbitMQ bu mesaj\u0131 ba\u015fka bir t\u00fcketiciye yeniden teslim eder.<\/p>\n<h2>Birden Fazla T\u00fcketiciye Mesaj \u0130letimi Senaryolar\u0131<\/h2>\n<p>RabbitMQ ve Puka&#8217;y\u0131 kullanarak birden fazla t\u00fcketiciye mesaj iletmenin iki ana senaryosu vard\u0131r: i\u015f y\u00fck\u00fcn\u00fc payla\u015fma (work queues) ve mesajlar\u0131 t\u00fcm t\u00fcketicilere yay\u0131nlama (publish\/subscribe).<\/p>\n<h3>Senaryo 1: \u0130\u015f Y\u00fck\u00fcn\u00fc Payla\u015ft\u0131rma (Work Queues)<\/h3>\n<p>Bu senaryoda, ayn\u0131 i\u015fi yapacak birden fazla t\u00fcketici vard\u0131r ve her mesaj sadece bir t\u00fcketici taraf\u0131ndan i\u015flenmelidir. RabbitMQ, mesajlar\u0131 kuyruktan t\u00fcketicilere round-robin (s\u0131rayla) da\u011f\u0131t\u0131r. Bu, i\u015f y\u00fck\u00fcn\u00fc dengelemek ve paralel i\u015flemeyi sa\u011flamak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<h4>Direct Exchange Kullan\u0131m\u0131<\/h4>\n<p>\u0130\u015f kuyruklar\u0131 genellikle <code>direct<\/code> exchange veya varsay\u0131lan (default) exchange kullan\u0131larak uygulan\u0131r. Varsay\u0131lan exchange, bo\u015f bir isimle temsil edilir ve g\u00f6nderilen mesaj\u0131n <code>routing key<\/code>&#8216;ini do\u011frudan ayn\u0131 isimdeki kuyru\u011fa y\u00f6nlendirir. Ancak, daha belirgin olmak i\u00e7in bir <code>direct<\/code> exchange kullanmak daha iyidir.<\/p>\n<p><strong>Producer (G\u00f6nderici) Kodu:<\/strong><\/p>\n<pre><code class=\"language-python\"># producer_work_queue.py\nimport puka\nfrom twisted.internet import reactor, defer\nimport time\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\nEXCHANGE_NAME = 'work_queue_exchange'\nQUEUE_NAME = 'task_queue'\nROUTING_KEY = 'tasks'\n\n@defer.inlineCallbacks\ndef send_tasks():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Producer (Work Queue): Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    yield client.exchange_declare(exchange=EXCHANGE_NAME, type='direct')\n    yield client.queue_declare(queue=QUEUE_NAME, durable=True) # Kuyru\u011fu kal\u0131c\u0131 yap\n    yield client.queue_bind(exchange=EXCHANGE_NAME, queue=QUEUE_NAME, routing_key=ROUTING_KEY)\n    print(f\"Producer: Exchange '{EXCHANGE_NAME}', Kuyruk '{QUEUE_NAME}' ve Binding '{ROUTING_KEY}' haz\u0131r.\")\n\n    for i in range(1, 11):\n        message_body = f\"Task {i}: Process this data.\"\n        # Mesaj\u0131 kal\u0131c\u0131 yap\n        yield client.basic_publish(exchange=EXCHANGE_NAME, routing_key=ROUTING_KEY, body=message_body,\n                                   properties={'delivery_mode': 2}) # delivery_mode=2 kal\u0131c\u0131 mesaj demektir\n        print(f\"Producer: G\u00f6rev g\u00f6nderildi: '{message_body}'\")\n        time.sleep(0.5)\n\n    print(\"Producer: T\u00fcm g\u00f6revler g\u00f6nderildi.\")\n    yield client.close()\n    reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(send_tasks)\n    reactor.run()<\/code><\/pre>\n<p>Burada <code>durable=True<\/code> ile kuyru\u011fu ve <code>delivery_mode=2<\/code> ile mesajlar\u0131 kal\u0131c\u0131 hale getirdik. Bu, RabbitMQ sunucusu yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda bile kuyru\u011fun ve i\u00e7indeki mesajlar\u0131n kaybolmamas\u0131n\u0131 sa\u011flar.<\/p>\n<p><strong>Consumer (T\u00fcketici) Kodu:<\/strong><\/p>\n<pre><code class=\"language-python\"># consumer_work_queue.py\nimport puka\nfrom twisted.internet import reactor, defer\nimport time\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\nQUEUE_NAME = 'task_queue'\n\n@defer.inlineCallbacks\ndef process_tasks():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Consumer (Work Queue): Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    yield client.queue_declare(queue=QUEUE_NAME, durable=True)\n    print(f\"Consumer: Kuyruk '{QUEUE_NAME}' haz\u0131r. G\u00f6revler bekleniyor...\")\n\n    # QoS (Quality of Service) ayar\u0131: Her t\u00fcketiciye ayn\u0131 anda sadece 1 mesaj g\u00f6nder\n    yield client.basic_qos(prefetch_count=1)\n\n    consume_result = yield client.basic_consume(queue=QUEUE_NAME, no_ack=False)\n\n    try:\n        while True:\n            message = yield consume_result.wait()\n            task_id = message['body'].split(':')[0]\n            print(f\"Consumer: G\u00f6rev al\u0131nd\u0131: '{message['body']}'\")\n            # G\u00f6rev i\u015fleme sim\u00fclasyonu\n            processing_time = len(message['body']) % 4 + 1 # G\u00f6rev uzunlu\u011funa g\u00f6re rastgele s\u00fcre\n            print(f\"Consumer: '{task_id}' i\u015fleniyor... ({processing_time} saniye)\")\n            time.sleep(processing_time)\n            \n            yield client.basic_ack(message['delivery_tag'])\n            print(f\"Consumer: G\u00f6rev '{task_id}' tamamland\u0131 ve onayland\u0131.\")\n    except KeyboardInterrupt:\n        print(\"Consumer: Kapat\u0131l\u0131yor...\")\n    finally:\n        yield client.close()\n        reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(process_tasks)\n    reactor.run()<\/code><\/pre>\n<p><code>basic_qos(prefetch_count=1)<\/code> ayar\u0131 \u00e7ok \u00f6nemlidir. Bu ayar, RabbitMQ&#8217;ya bir t\u00fcketiciye ayn\u0131 anda sadece bir mesaj g\u00f6ndermesini s\u00f6yler. T\u00fcketici bu mesaj\u0131 onaylamadan (ACK) \u00f6nce ba\u015fka bir mesaj almaz. Bu, t\u00fcketiciler aras\u0131nda i\u015f y\u00fck\u00fcn\u00fcn adil bir \u015fekilde da\u011f\u0131t\u0131lmas\u0131n\u0131 ve bir t\u00fcketicinin di\u011ferlerinden daha yava\u015f \u00e7al\u0131\u015fmas\u0131 durumunda bile mesajlar\u0131n y\u0131\u011f\u0131lmamas\u0131n\u0131 sa\u011flar. Birden fazla <code>consumer_work_queue.py<\/code> \u00f6rne\u011fi \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, g\u00f6revlerin aralar\u0131nda payla\u015f\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6receksiniz.<\/p>\n<h3>Senaryo 2: Mesajlar\u0131 T\u00fcm T\u00fcketicilere Yay\u0131nlama (Publish\/Subscribe)<\/h3>\n<p>Bu senaryoda, bir \u00fcretici taraf\u0131ndan g\u00f6nderilen mesaj\u0131n, o exchange&#8217;e ba\u011fl\u0131 olan t\u00fcm aktif t\u00fcketicilere ula\u015fmas\u0131 istenir. Bu, bir olay yay\u0131nlama (event broadcasting) veya bildirim g\u00f6nderme gibi durumlarda kullan\u0131l\u0131r.<\/p>\n<h4>Fanout Exchange Kullan\u0131m\u0131<\/h4>\n<p><code>fanout<\/code> exchange, bu t\u00fcr yay\u0131nlama senaryolar\u0131 i\u00e7in tasarlanm\u0131\u015ft\u0131r. Bir <code>fanout<\/code> exchange&#8217;e g\u00f6nderilen her mesaj, kendisine ba\u011fl\u0131 olan t\u00fcm kuyruklara kopyalan\u0131r ve bu kuyruklar\u0131 dinleyen t\u00fcketicilere iletilir. <code>routing key<\/code> bu exchange t\u00fcr\u00fcnde g\u00f6z ard\u0131 edilir.<\/p>\n<h4>Ge\u00e7ici Kuyruklar ve Otomatik Silme<\/h4>\n<p>Publish\/Subscribe modelinde, her t\u00fcketicinin genellikle kendi ge\u00e7ici kuyru\u011funa sahip olmas\u0131 istenir. Bu kuyruklar, t\u00fcketici ba\u011flant\u0131s\u0131 kesildi\u011finde otomatik olarak silinmelidir. Puka&#8217;da <code>queue_declare(exclusive=True, auto_delete=True)<\/code> ile bu sa\u011flan\u0131r. <code>exclusive=True<\/code> kuyru\u011fu sadece bildiren ba\u011flant\u0131n\u0131n kullanabilece\u011fi anlam\u0131na gelirken, <code>auto_delete=True<\/code> son t\u00fcketici ba\u011flant\u0131s\u0131 kesildi\u011finde kuyru\u011fun otomatik olarak silinmesini sa\u011flar.<\/p>\n<p><strong>Producer (G\u00f6nderici) Kodu:<\/strong><\/p>\n<pre><code class=\"language-python\"># producer_fanout.py\nimport puka\nfrom twisted.internet import reactor, defer\nimport time\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\nEXCHANGE_NAME = 'weather_updates'\n\n@defer.inlineCallbacks\ndef send_weather_updates():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Producer (Fanout): Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    yield client.exchange_declare(exchange=EXCHANGE_NAME, type='fanout')\n    print(f\"Producer: Exchange '{EXCHANGE_NAME}' bildirildi.\")\n\n    updates = [\"G\u00fcne\u015fli ve s\u0131cak\", \"Hafif ya\u011fmur bekleniyor\", \"R\u00fczgarl\u0131 ve so\u011fuk\", \"Kar ya\u011f\u0131\u015f\u0131 ihtimali\"]\n    for i, update in enumerate(updates):\n        message_body = f\"Hava Durumu G\u00fcncellemesi {i+1}: {update}\"\n        yield client.basic_publish(exchange=EXCHANGE_NAME, routing_key='', body=message_body)\n        print(f\"Producer: Hava durumu g\u00fcncellendi: '{message_body}'\")\n        time.sleep(1)\n\n    print(\"Producer: T\u00fcm g\u00fcncellemeler g\u00f6nderildi.\")\n    yield client.close()\n    reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(send_weather_updates)\n    reactor.run()<\/code><\/pre>\n<p><code>fanout<\/code> exchange kulland\u0131\u011f\u0131m\u0131z i\u00e7in <code>routing_key<\/code> bo\u015f b\u0131rak\u0131lm\u0131\u015ft\u0131r.<\/p>\n<p><strong>Consumer (T\u00fcketici) Kodu:<\/strong><\/p>\n<pre><code class=\"language-python\"># consumer_fanout.py\nimport puka\nfrom twisted.internet import reactor, defer\nimport time\n\nRABBITMQ_URL = \"amqp:\/\/guest:guest@localhost:5672\/\"\nEXCHANGE_NAME = 'weather_updates'\n\n@defer.inlineCallbacks\ndef receive_weather_updates():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    print(\"Consumer (Fanout): Ba\u011flant\u0131 ba\u015far\u0131l\u0131.\")\n\n    yield client.exchange_declare(exchange=EXCHANGE_NAME, type='fanout')\n    \n    # Ge\u00e7ici, exclusive ve auto-delete kuyruk olu\u015ftur\n    result = yield client.queue_declare(exclusive=True, auto_delete=True)\n    queue_name = result['queue']\n    print(f\"Consumer: Ge\u00e7ici kuyruk olu\u015fturuldu: '{queue_name}'\")\n\n    yield client.queue_bind(exchange=EXCHANGE_NAME, queue=queue_name, routing_key='')\n    print(f\"Consumer: Exchange '{EXCHANGE_NAME}' ile kuyruk '{queue_name}' ba\u011fland\u0131.\")\n    print(\"Consumer: Hava durumu g\u00fcncellemeleri bekleniyor. \u00c7\u0131kmak i\u00e7in Ctrl+C.\")\n\n    consume_result = yield client.basic_consume(queue=queue_name, no_ack=False)\n\n    try:\n        while True:\n            message = yield consume_result.wait()\n            print(f\"Consumer: Hava durumu al\u0131nd\u0131: '{message['body']}'\")\n            yield client.basic_ack(message['delivery_tag'])\n    except KeyboardInterrupt:\n        print(\"Consumer: Kapat\u0131l\u0131yor...\")\n    finally:\n        yield client.close()\n        reactor.stop()\n\nif __name__ == \"__main__\":\n    reactor.callWhenRunning(receive_weather_updates)\n    reactor.run()<\/code><\/pre>\n<p>Birden fazla <code>consumer_fanout.py<\/code> \u00f6rne\u011fi \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, her bir t\u00fcketicinin ayn\u0131 hava durumu g\u00fcncellemelerini ald\u0131\u011f\u0131n\u0131 g\u00f6receksiniz. Her t\u00fcketici kendi \u00f6zel ge\u00e7ici kuyru\u011funa sahip oldu\u011fundan, mesajlar her birine ayr\u0131 ayr\u0131 teslim edilir.<\/p>\n<h2>Geli\u015fmi\u015f Konular ve G\u00fcvenilirlik<\/h2>\n<p>Mesajla\u015fma sistemlerinde g\u00fcvenilirlik, mesajlar\u0131n kaybolmamas\u0131n\u0131 ve do\u011fru bir \u015fekilde i\u015flenmesini sa\u011flamak i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<h3>Mesaj Kal\u0131c\u0131l\u0131\u011f\u0131 (Message Durability)<\/h3>\n<p>RabbitMQ, varsay\u0131lan olarak mesajlar\u0131 ve kuyruklar\u0131 haf\u0131zada tutar. Bu, sunucu yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda mesajlar\u0131n veya kuyruklar\u0131n kaybolabilece\u011fi anlam\u0131na gelir. Kal\u0131c\u0131l\u0131\u011f\u0131 sa\u011flamak i\u00e7in:<br \/>\n*   <strong>Kuyruklar\u0131 Kal\u0131c\u0131 Yapma:<\/strong> <code>client.queue_declare(queue='my_queue', durable=True)<\/code><br \/>\n*   <strong>Mesajlar\u0131 Kal\u0131c\u0131 Yapma:<\/strong> <code>client.basic_publish(..., properties={'delivery_mode': 2})<\/code>. <code>delivery_mode=2<\/code> mesaj\u0131n diske yaz\u0131lmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>Bu ayarlar, RabbitMQ sunucusu beklenmedik bir \u015fekilde kapand\u0131\u011f\u0131nda bile mesajlar\u0131n ve kuyruklar\u0131n korunmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<h3>Publisher Confirms<\/h3>\n<p>\u00dcreticinin bir mesaj\u0131 RabbitMQ&#8217;ya g\u00f6nderdi\u011finden ve RabbitMQ&#8217;nun mesaj\u0131 ba\u015far\u0131yla kabul etti\u011finden emin olman\u0131n yolu <code>publisher confirms<\/code> kullanmakt\u0131r. Bu \u00f6zellik etkinle\u015ftirildi\u011finde, RabbitMQ mesaj\u0131 kabul etti\u011finde \u00fcreticiye bir onay (ACK) g\u00f6nderir. E\u011fer bir sorun olursa (\u00f6rne\u011fin, mesaj bir exchange&#8217;e y\u00f6nlendirilemezse), bir NACK g\u00f6nderilir. Puka&#8217;da <code>client.confirm_select()<\/code> ile bu modu etkinle\u015ftirebilir ve <code>basic_publish<\/code> metodunun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc <code>Deferred<\/code> nesnesini bekleyerek onay\u0131 alabilirsiniz.<\/p>\n<pre><code class=\"language-python\"># Publisher Confirms \u00f6rne\u011fi\n@defer.inlineCallbacks\ndef send_with_confirm():\n    client = puka.Client(RABBITMQ_URL)\n    yield client.connect()\n    yield client.confirm_select() # Publisher Confirms modunu etkinle\u015ftir\n\n    exchange_name = 'my_direct_exchange'\n    routing_key = 'test'\n    yield client.exchange_declare(exchange=exchange_name, type='direct')\n\n    message_body = \"Mesaj onaylanacak m\u0131?\"\n    confirm_deferred = yield client.basic_publish(exchange=exchange_name, routing_key=routing_key, body=message_body)\n    \n    try:\n        # Onay bekleyelim\n        confirm_result = yield confirm_deferred\n        if confirm_result.get('ack'):\n            print(f\"Mesaj ba\u015far\u0131yla onayland\u0131: '{message_body}'\")\n        else:\n            print(f\"Mesaj onaylanmad\u0131 (NACK): '{message_body}'\")\n    except Exception as e:\n        print(f\"Mesaj onay\u0131 al\u0131namad\u0131: {e}\")\n    finally:\n        yield client.close()\n        reactor.stop()<\/code><\/pre>\n<h3>T\u00fcketici Taraf\u0131nda Hata Y\u00f6netimi: NACK ve Requeue<\/h3>\n<p>Bir t\u00fcketici mesaj\u0131 i\u015flerken bir hata ile kar\u015f\u0131la\u015f\u0131rsa, mesaj\u0131 onaylamak (ACK) yerine reddedebilir (NACK &#8211; Negative Acknowledge). <code>basic_nack<\/code> metodu ile bu yap\u0131l\u0131r. <code>requeue=True<\/code> parametresi ile mesaj\u0131n kuyru\u011fa geri g\u00f6nderilerek ba\u015fka bir t\u00fcketici taraf\u0131ndan tekrar i\u015flenmesi sa\u011flanabilir.<\/p>\n<pre><code class=\"language-python\"># Consumer'da NACK \u00f6rne\u011fi\n<h2>... (ba\u011flant\u0131 ve kuyruk bildirimleri)<\/h2>\nconsume_result = yield client.basic_consume(queue=queue_name, no_ack=False)\ntry:\n    while True:\n        message = yield consume_result.wait()\n        try:\n            # Hata olu\u015fabilecek bir i\u015flem\n            if \"hata\" in message['body']:\n                raise ValueError(\"Mesajda hata var!\")\n            \n            print(f\"Mesaj i\u015fleniyor: '{message['body']}'\")\n            # Ba\u015far\u0131l\u0131 i\u015flem sonras\u0131 ACK\n            yield client.basic_ack(message['delivery_tag'])\n            print(f\"Mesaj onayland\u0131: {message['delivery_tag']}\")\n        except ValueError as e:\n            print(f\"Hata olu\u015ftu: {e}. Mesaj yeniden kuyru\u011fa g\u00f6nderiliyor: '{message['body']}'\")\n            # Hata durumunda NACK ve yeniden kuyru\u011fa g\u00f6nderme\n            yield client.basic_nack(message['delivery_tag'], requeue=True)\nexcept KeyboardInterrupt:\n    print(\"Kapat\u0131l\u0131yor...\")\nfinally:\n    yield client.close()\n    reactor.stop()<\/code><\/pre>\n<p><code>basic_reject<\/code> metodu da benzer \u015fekilde mesaj\u0131 reddetmek i\u00e7in kullan\u0131l\u0131r, ancak <code>basic_nack<\/code>&#8216;ten farkl\u0131 olarak toplu NACK yapamaz.<\/p>\n<h3>\u00d6nceden Getirme Say\u0131s\u0131 (Prefetch Count \/ QoS)<\/h3>\n<p>Daha \u00f6nce de bahsetti\u011fimiz <code>basic_qos(prefetch_count=N)<\/code> ayar\u0131, bir t\u00fcketicinin ayn\u0131 anda ka\u00e7 mesaj\u0131 i\u015fleyebilece\u011fini belirtir. Bu, i\u015f y\u00fck\u00fcn\u00fc adil bir \u015fekilde da\u011f\u0131tmak ve yava\u015f t\u00fcketicilerin mesaj y\u0131\u011f\u0131lmas\u0131na neden olmas\u0131n\u0131 \u00f6nlemek i\u00e7in \u00e7ok \u00f6nemlidir. <code>prefetch_count=1<\/code> genellikle en g\u00fcvenli ayard\u0131r, ancak daha y\u00fcksek de\u011ferler belirli senaryolarda performans\u0131 art\u0131rabilir (e\u011fer t\u00fcketiciler mesajlar\u0131 \u00e7ok h\u0131zl\u0131 i\u015fleyebiliyorsa).<\/p>\n<h2>Performans ve \u00d6l\u00e7eklenebilirlik \u0130pu\u00e7lar\u0131<\/h2>\n<p>RabbitMQ ve Puka tabanl\u0131 bir sistemin performans\u0131n\u0131 ve \u00f6l\u00e7eklenebilirli\u011fini art\u0131rmak i\u00e7in baz\u0131 stratejiler:<\/p>\n<h3>T\u00fcketici Say\u0131s\u0131n\u0131 Art\u0131rma<\/h3>\n<p>\u0130\u015f y\u00fck\u00fcn\u00fc payla\u015ft\u0131rma senaryosunda, i\u015flem g\u00fcc\u00fcn\u00fc art\u0131rmak i\u00e7in ayn\u0131 t\u00fcketici uygulamas\u0131ndan birden fazla \u00f6rnek \u00e7al\u0131\u015ft\u0131rabilirsiniz. RabbitMQ, mesajlar\u0131 bu t\u00fcketiciler aras\u0131nda otomatik olarak da\u011f\u0131tacakt\u0131r.<\/p>\n<h3>Mesaj Boyutlar\u0131 ve Serile\u015ftirme<\/h3>\n<p>K\u00fc\u00e7\u00fck mesajlar, genellikle b\u00fcy\u00fck mesajlardan daha h\u0131zl\u0131 i\u015flenir. E\u011fer \u00e7ok b\u00fcy\u00fck veriler g\u00f6ndermeniz gerekiyorsa, bu verileri bir depolama servisine (\u00f6rn. S3, MinIO) kaydedip, mesaj kuyru\u011funda sadece bu verinin referans\u0131n\u0131 (URL veya ID) g\u00f6ndermek daha verimli olabilir. Mesaj i\u00e7eri\u011fi genellikle JSON, Protobuf veya MessagePack gibi hafif serile\u015ftirme formatlar\u0131nda olmal\u0131d\u0131r.<\/p>\n<h3>Exchange ve Kuyruk Tasar\u0131m\u0131<\/h3>\n<p>*   <strong>Do\u011fru Exchange T\u00fcr\u00fcn\u00fc Se\u00e7in:<\/strong> \u0130htiyac\u0131n\u0131za uygun exchange t\u00fcr\u00fcn\u00fc se\u00e7mek (direct, fanout, topic) performans\u0131 ve y\u00f6nlendirme mant\u0131\u011f\u0131n\u0131 optimize eder.<br \/>\n*   <strong>Kuyruk Say\u0131s\u0131:<\/strong> \u00c7ok fazla k\u00fc\u00e7\u00fck kuyruk yerine, benzer mesajlar\u0131 i\u015fleyen daha az say\u0131da kuyruk kullanmak daha verimli olabilir.<br \/>\n*   <strong>Kuyruk Parametreleri:<\/strong> <code>durable<\/code>, <code>exclusive<\/code>, <code>auto_delete<\/code>, <code>message-ttl<\/code> gibi kuyruk parametrelerini dikkatli kullan\u0131n. \u00d6zellikle <code>message-ttl<\/code> (mesaj \u00f6mr\u00fc) ve <code>dead-letter-exchange<\/code> (i\u015flenemeyen mesajlar i\u00e7in) gibi \u00f6zellikler, hata y\u00f6netimi ve sistem dayan\u0131kl\u0131l\u0131\u011f\u0131 i\u00e7in \u00f6nemlidir.<\/p>\n<h2>Puka&#8217;n\u0131n Gelece\u011fi ve Alternatifler<\/h2>\n<h3>Puka&#8217;n\u0131n Durumu<\/h3>\n<p>Puka, Twisted ekosistemi i\u00e7inde asenkron RabbitMQ istemcisi olarak de\u011ferli bir rol oynam\u0131\u015ft\u0131r. Ancak, projenin aktif geli\u015ftirme ve bak\u0131m\u0131n\u0131n Pika veya aio-pika gibi di\u011fer k\u00fct\u00fcphanelere k\u0131yasla daha yava\u015f oldu\u011fu g\u00f6zlemlenmektedir. Bu, yeni Python s\u00fcr\u00fcmleriyle veya AMQP protokol\u00fcndeki de\u011fi\u015fikliklerle uyumluluk sorunlar\u0131na yol a\u00e7abilir. Proje se\u00e7imi yaparken bu fakt\u00f6r\u00fc g\u00f6z \u00f6n\u00fcnde bulundurmak \u00f6nemlidir.<\/p>\n<h3>Alternatif Python K\u00fct\u00fcphaneleri<\/h3>\n<p>*   <strong>Pika:<\/strong> Python i\u00e7in en pop\u00fcler RabbitMQ istemcisidir. Hem senkron hem de asenkron (asyncio ile uyumlu) ba\u011flant\u0131 se\u00e7enekleri sunar. Geni\u015f topluluk deste\u011fi ve aktif geli\u015ftirme s\u00fcrecine sahiptir.<br \/>\n*   <strong>aio-pika:<\/strong> Python&#8217;\u0131n yerle\u015fik <code>asyncio<\/code> k\u00fct\u00fcphanesi \u00fczerine in\u015fa edilmi\u015f, tamamen asenkron bir RabbitMQ istemcisidir. Modern Python asenkron programlama paradigmalar\u0131na daha uygun bir yakla\u015f\u0131md\u0131r.<\/p>\n<p>E\u011fer yeni bir projeye ba\u015fl\u0131yorsan\u0131z ve Twisted kullanm\u0131yorsan\u0131z, Pika veya aio-pika genellikle daha g\u00fcncel ve desteklenen se\u00e7enekler olarak \u00f6ne \u00e7\u0131kar. Ancak, mevcut bir Twisted projesindeyseniz, Puka hala entegrasyon kolayl\u0131\u011f\u0131 sa\u011flayabilir.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>RabbitMQ ve Python&#8217;\u0131n Puka k\u00fct\u00fcphanesi, da\u011f\u0131t\u0131k sistemlerde g\u00fcvenilir ve \u00f6l\u00e7eklenebilir mesaj iletimi i\u00e7in g\u00fc\u00e7l\u00fc bir kombinasyon sunar. Mesaj kuyruklar\u0131, uygulama bile\u015fenleri aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 azaltarak, sistemin esnekli\u011fini ve dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r. Puka&#8217;n\u0131n asenkron yap\u0131s\u0131 ve Twisted entegrasyonu, \u00f6zellikle y\u00fcksek e\u015fzamanl\u0131l\u0131k gerektiren Python uygulamalar\u0131nda mesajla\u015fma yeteneklerini g\u00fc\u00e7lendirir.<\/p>\n<p>Bu makalede, RabbitMQ&#8217;nun temel kavramlar\u0131ndan (Exchange, Kuyruk, Binding) Puka ile ba\u011flant\u0131 kurmaya, mesaj g\u00f6ndermeye ve almaya kadar ad\u0131m ad\u0131m ilerledik. \u00d6zellikle birden fazla t\u00fcketiciye mesaj iletmek i\u00e7in kullan\u0131lan iki ana senaryoyu (i\u015f y\u00fck\u00fcn\u00fc payla\u015fma i\u00e7in <code>direct<\/code> exchange ve yay\u0131nlama i\u00e7in <code>fanout<\/code> exchange) detayl\u0131 kod \u00f6rnekleriyle inceledik. Mesaj kal\u0131c\u0131l\u0131\u011f\u0131, publisher confirms ve prefetch count gibi g\u00fcvenilirlik ve performans ipu\u00e7lar\u0131na da de\u011findik.<\/p>\n<p>Her ne kadar Puka&#8217;n\u0131n aktif geli\u015ftirme durumu di\u011fer k\u00fct\u00fcphanelere g\u00f6re biraz daha yava\u015f olsa da, Twisted ekosistemi i\u00e7inde hala ge\u00e7erli bir se\u00e7enektir. Mesaj kuyruklar\u0131n\u0131n g\u00fcc\u00fcn\u00fc anlamak ve do\u011fru ara\u00e7larla uygulamak, modern, da\u011f\u0131t\u0131k sistemlerin ba\u015far\u0131l\u0131 bir \u015fekilde in\u015fa edilmesinde temel bir ad\u0131md\u0131r. Bu bilgiler \u0131\u015f\u0131\u011f\u0131nda, projelerinizde RabbitMQ ve Puka&#8217;y\u0131 kullanarak sa\u011flam ve \u00f6l\u00e7eklenebilir ileti\u015fim altyap\u0131lar\u0131 olu\u015fturabilirsiniz.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi\nGiri\u015f: Mesaj Kuyruklar\u0131 ve Da\u011f\u0131t\u0131k Sistemler\nG\u00fcn\u00fcm\u00fcz\u00fcn","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1403],"tags":[],"class_list":{"0":"post-30426","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-python","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RabbitMQ ve Python&#039;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RabbitMQ ve Python&#039;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi\" \/>\n<meta property=\"og:description\" content=\"RabbitMQ ve Python&#039;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi Giri\u015f: Mesaj Kuyruklar\u0131 ve Da\u011f\u0131t\u0131k Sistemler G\u00fcn\u00fcm\u00fcz\u00fcn\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-27T14:41:52+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi\",\"datePublished\":\"2025-09-27T14:41:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\"},\"wordCount\":3130,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Python\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\",\"name\":\"RabbitMQ ve Python'\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-09-27T14:41:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"RabbitMQ ve Python'\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/","og_locale":"tr_TR","og_type":"article","og_title":"RabbitMQ ve Python'\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi","og_description":"RabbitMQ ve Python'\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi Giri\u015f: Mesaj Kuyruklar\u0131 ve Da\u011f\u0131t\u0131k Sistemler G\u00fcn\u00fcm\u00fcz\u00fcn","og_url":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-09-27T14:41:52+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi","datePublished":"2025-09-27T14:41:52+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/"},"wordCount":3130,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Python"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/","url":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/","name":"RabbitMQ ve Python'\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-09-27T14:41:52+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/rabbitmq-ve-pythonin-puka-kutuphanesi-ile-birden-fazla-tuketiciye-mesaj-iletimi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"RabbitMQ ve Python&#8217;\u0131n Puka K\u00fct\u00fcphanesi ile Birden Fazla T\u00fcketiciye Mesaj \u0130letimi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=30426"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30426\/revisions"}],"predecessor-version":[{"id":30427,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30426\/revisions\/30427"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=30426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=30426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=30426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}