{"id":37550,"date":"2026-01-08T20:41:08","date_gmt":"2026-01-08T17:41:08","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=37550"},"modified":"2026-01-08T20:41:08","modified_gmt":"2026-01-08T17:41:08","slug":"publish-subscribe-yayinla-abone-ol-deseni-node-jste","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/","title":{"rendered":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te"},"content":{"rendered":"<p><body><\/p>\n<h2>Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te<\/h2>\n<p>Publish\/Subscribe (Pub\/Sub) deseni, modern yaz\u0131l\u0131m mimarilerinde, \u00f6zellikle da\u011f\u0131t\u0131k sistemlerde ve olay odakl\u0131 uygulamalarda merkezi bir rol oynayan g\u00fc\u00e7l\u00fc bir mesajla\u015fma modelidir. Node.js&#8217;in asenkron ve olay odakl\u0131 do\u011fas\u0131, bu desenin platform \u00fczerinde do\u011fal ve verimli bir \u015fekilde uygulanmas\u0131na olanak tan\u0131r. Bu makale, Publish\/Subscribe deseninin temel prensiplerini, Node.js ekosistemindeki \u00e7e\u015fitli uygulama y\u00f6ntemlerini, avantajlar\u0131n\u0131, dezavantajlar\u0131n\u0131 ve en iyi kullan\u0131m senaryolar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceleyecektir.<\/p>\n<h3>Giri\u015f: Neden Publish\/Subscribe?<\/h3>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn karma\u015f\u0131k yaz\u0131l\u0131m sistemleri, genellikle birden fazla bile\u015fenin veya servisin birbiriyle ileti\u015fim kurmas\u0131n\u0131 gerektirir. Geleneksel do\u011frudan ileti\u015fim y\u00f6ntemleri (\u00f6rne\u011fin, HTTP \u00e7a\u011fr\u0131lar\u0131), bile\u015fenler aras\u0131nda s\u0131k\u0131 bir ba\u011f\u0131ml\u0131l\u0131k yaratabilir. Bu durum, sistemin esnekli\u011fini, \u00f6l\u00e7eklenebilirli\u011fini ve bak\u0131m\u0131n\u0131 zorla\u015ft\u0131r\u0131r. \u0130\u015fte bu noktada Publish\/Subscribe deseni devreye girer.<\/p>\n<p>Publish\/Subscribe deseni, bile\u015fenler aras\u0131nda gev\u015fek ba\u011fl\u0131 bir ileti\u015fim sa\u011flaman\u0131n anahtar\u0131d\u0131r. Bir bile\u015fen (yay\u0131nc\u0131), belirli bir olay\u0131 veya mesaj\u0131 yay\u0131nlar ve bu olay\u0131 \u00f6nemseyen di\u011fer bile\u015fenler (aboneler) bu olaya abone olur. Yay\u0131nc\u0131 ve abone, birbirlerinin varl\u0131\u011f\u0131ndan do\u011frudan haberdar olmak zorunda de\u011fildir; aralar\u0131ndaki ileti\u015fimi bir arac\u0131 (broker veya olay veri yolu) y\u00f6netir. Node.js&#8217;in kendisi de, <code>EventEmitter<\/code> gibi yerle\u015fik mekanizmalar\u0131yla olay odakl\u0131 programlamay\u0131 te\u015fvik etti\u011fi i\u00e7in, Pub\/Sub deseniyle m\u00fckemmel bir uyum i\u00e7indedir.<\/p>\n<h3>Publish\/Subscribe Deseni Temelleri<\/h3>\n<p>Publish\/Subscribe deseni, temel olarak \u00fc\u00e7 ana bile\u015fenden olu\u015fur: Yay\u0131nc\u0131lar (Publishers), Aboneler (Subscribers) ve bir Mesaj Arac\u0131s\u0131 (Broker) veya Olay Veri Yolu (Event Bus).<\/p>\n<h4>Nedir?<\/h4>\n<p>Publish\/Subscribe, bir mesajla\u015fma kal\u0131b\u0131d\u0131r ve g\u00f6ndericilerin (yay\u0131nc\u0131lar) mesajlar\u0131 do\u011frudan belirli al\u0131c\u0131lara g\u00f6ndermesi yerine, belirli bir &#8220;konuya&#8221; veya &#8220;kanala&#8221; mesaj yay\u0131nlamas\u0131n\u0131 sa\u011flar. Bu konulara abone olan al\u0131c\u0131lar (aboneler) ise yay\u0131nlanan mesajlar\u0131 otomatik olarak al\u0131r. Bu model, g\u00f6nderici ve al\u0131c\u0131 aras\u0131nda do\u011frudan bir ba\u011flant\u0131 kurulmas\u0131n\u0131 engeller, b\u00f6ylece sistemin genel ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n\u0131 azalt\u0131r.<\/p>\n<h4>Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h4>\n<p>\u0130\u015f ak\u0131\u015f\u0131 olduk\u00e7a basittir:<br \/>\n1.  <strong>Yay\u0131nc\u0131:<\/strong> Belirli bir olay\u0131n ger\u00e7ekle\u015fti\u011fini veya bir mesaj\u0131n g\u00f6nderilmesi gerekti\u011fini fark eder.<br \/>\n2.  <strong>Yay\u0131nlama:<\/strong> Yay\u0131nc\u0131, bu olay\u0131 veya mesaj\u0131, ilgili konuya veya kanala arac\u0131l\u0131\u011f\u0131yla yay\u0131nlar. Yay\u0131nc\u0131, mesaj\u0131n kimler taraf\u0131ndan al\u0131naca\u011f\u0131n\u0131 bilmez ve umursamaz.<br \/>\n3.  <strong>Abone Olma:<\/strong> Abone olmak isteyen bile\u015fenler, ilgilendikleri konulara veya kanallara arac\u0131l\u0131\u011f\u0131yla abone olurlar.<br \/>\n4.  <strong>Mesaj Teslimat\u0131:<\/strong> Arac\u0131, yay\u0131nlanan mesaj\u0131, o konuya abone olan t\u00fcm abonelere iletir.<\/p>\n<h4>Publisher (Yay\u0131nc\u0131)<\/h4>\n<p>Yay\u0131nc\u0131lar, belirli olaylar\u0131 veya durum de\u011fi\u015fikliklerini sisteme duyuran bile\u015fenlerdir. Bir yay\u0131nc\u0131, bir olay\u0131n meydana geldi\u011fini alg\u0131lad\u0131\u011f\u0131nda, bu olay\u0131 bir mesaj olarak bi\u00e7imlendirir ve arac\u0131ya g\u00f6nderir. Yay\u0131nc\u0131n\u0131n tek sorumlulu\u011fu, mesaj\u0131 do\u011fru konuya yay\u0131nlamak ve arac\u0131n\u0131n mesaj\u0131 teslim edece\u011fine g\u00fcvenmektir. \u00d6rne\u011fin, bir e-ticaret uygulamas\u0131nda &#8220;sipari\u015f verildi&#8221; veya &#8220;\u00fcr\u00fcn stokta t\u00fckendi&#8221; gibi olaylar\u0131 yay\u0131nlayabilir.<\/p>\n<h4>Subscriber (Abone)<\/h4>\n<p>Aboneler, belirli olaylarla ilgilenen ve bu olaylar meydana geldi\u011finde tepki veren bile\u015fenlerdir. Bir abone, ilgilendi\u011fi konulara abone olur ve bu konularda yay\u0131nlanan mesajlar\u0131 al\u0131r. Mesaj\u0131 ald\u0131\u011f\u0131nda, abone kendi i\u015f mant\u0131\u011f\u0131na g\u00f6re bir eylem ger\u00e7ekle\u015ftirir. \u00d6rne\u011fin, &#8220;sipari\u015f verildi&#8221; olay\u0131na abone olan bir e-posta servisi, m\u00fc\u015fteriye sipari\u015f onay\u0131 e-postas\u0131 g\u00f6nderebilir.<\/p>\n<h4>Broker\/Event Bus (Olay Veri Yolu)<\/h4>\n<p>Broker veya Olay Veri Yolu, Publish\/Subscribe deseninin merkezi bile\u015fenidir. Yay\u0131nc\u0131lar ve aboneler aras\u0131ndaki ileti\u015fimi y\u00f6netir. Yay\u0131nc\u0131lardan gelen mesajlar\u0131 al\u0131r, bunlar\u0131 ilgili konulara g\u00f6re y\u00f6nlendirir ve o konulara abone olan t\u00fcm abonelere iletir. Broker, yay\u0131nc\u0131lar ve aboneler aras\u0131ndaki gev\u015fek ba\u011fl\u0131l\u0131\u011f\u0131 sa\u011flayan arac\u0131d\u0131r. Bu arac\u0131, tek bir uygulama i\u00e7indeki basit bir <code>EventEmitter<\/code> \u00f6rne\u011fi olabilece\u011fi gibi, da\u011f\u0131t\u0131k sistemler i\u00e7in Redis, RabbitMQ veya Apache Kafka gibi karma\u015f\u0131k mesaj kuyru\u011fu sistemleri de olabilir.<\/p>\n<h3>Publish\/Subscribe ve Observer Deseni Aras\u0131ndaki Farklar<\/h3>\n<p>Publish\/Subscribe ve Observer desenleri, y\u00fczeysel olarak benzer g\u00f6r\u00fcnse de, \u00f6nemli mimari farkl\u0131l\u0131klara sahiptir. Her ikisi de bir nesnenin durumundaki de\u011fi\u015fiklikleri di\u011fer nesnelere bildirme amac\u0131na hizmet eder, ancak bunu farkl\u0131 \u015fekillerde yaparlar.<\/p>\n<p><strong>Observer Deseni:<\/strong><br \/>\n*   <strong>Do\u011frudan Ba\u011fl\u0131l\u0131k:<\/strong> G\u00f6zlemlenen (Subject) nesne, g\u00f6zlemcilerin (Observer) bir listesini tutar ve bir olay meydana geldi\u011finde bu listeyi do\u011frudan d\u00f6ng\u00fcye sokarak her g\u00f6zlemcinin bir metodunu \u00e7a\u011f\u0131r\u0131r.<br \/>\n*   <strong>Senkron \u0130leti\u015fim:<\/strong> Genellikle ayn\u0131 i\u015flem i\u00e7inde ve senkron bir \u015fekilde \u00e7al\u0131\u015f\u0131r.<br \/>\n*   <strong>Bilgi Sahibi Olma:<\/strong> G\u00f6zlemlenen, kimlerin kendisini g\u00f6zlemledi\u011fini bilir. G\u00f6zlemciler de genellikle belirli bir g\u00f6zlemlenene ba\u011fl\u0131d\u0131r.<br \/>\n*   <strong>\u00d6rnek:<\/strong> DOM olaylar\u0131 (<code>addEventListener<\/code>), Node.js <code>EventEmitter<\/code>&#8216;\u0131n tek bir i\u015flem i\u00e7indeki kullan\u0131m\u0131.<\/p>\n<p><strong>Publish\/Subscribe Deseni:<\/strong><br \/>\n*   <strong>Gev\u015fek Ba\u011fl\u0131l\u0131k:<\/strong> Yay\u0131nc\u0131 ve abone aras\u0131nda do\u011frudan bir ba\u011flant\u0131 yoktur. Bir arac\u0131 (broker) bu ileti\u015fimi y\u00f6netir. Yay\u0131nc\u0131, kimlerin abone oldu\u011funu bilmez; aboneler de kimin yay\u0131nlad\u0131\u011f\u0131n\u0131 bilmez.<br \/>\n*   <strong>Asenkron \u0130leti\u015fim:<\/strong> Genellikle asenkron ve da\u011f\u0131t\u0131k sistemlerde kullan\u0131l\u0131r. Mesajlar, broker arac\u0131l\u0131\u011f\u0131yla iletildi\u011fi i\u00e7in gecikmeler olabilir.<br \/>\n*   <strong>Arac\u0131 (Broker):<\/strong> \u0130leti\u015fimin merkezi noktas\u0131d\u0131r. Mesajlar\u0131 al\u0131r ve ilgili abonelere y\u00f6nlendirir.<br \/>\n*   <strong>\u00d6rnek:<\/strong> Mikroservisler aras\u0131 ileti\u015fimde Redis Pub\/Sub, RabbitMQ, Kafka.<\/p>\n<p>Temel fark, Observer deseninde g\u00f6zlemlenenin g\u00f6zlemcilere do\u011frudan referanslar tutmas\u0131 ve onlarla do\u011frudan ileti\u015fim kurmas\u0131d\u0131r. Publish\/Subscribe deseninde ise yay\u0131nc\u0131 ve abone aras\u0131nda bir arac\u0131 bulunur ve bu arac\u0131, ileti\u015fimi tamamen soyutlar. Bu soyutlama, Pub\/Sub desenini da\u011f\u0131t\u0131k sistemler i\u00e7in \u00e7ok daha uygun hale getirir.<\/p>\n<h3>Node.js&#8217;te Publish\/Subscribe Uygulamalar\u0131<\/h3>\n<p>Node.js&#8217;in olay odakl\u0131 mimarisi, Publish\/Subscribe desenini uygulamak i\u00e7in do\u011fal bir zemin sunar. Hem yerel (tek i\u015flem i\u00e7i) hem de da\u011f\u0131t\u0131k (birden fazla i\u015flem veya servis aras\u0131) \u00e7\u00f6z\u00fcmler mevcuttur.<\/p>\n<h4>Yerel Olay Yay\u0131c\u0131lar (EventEmitter)<\/h4>\n<p>Node.js&#8217;in \u00e7ekirdek <code>events<\/code> mod\u00fcl\u00fc, tek bir Node.js i\u015flemi i\u00e7inde Pub\/Sub benzeri bir desen uygulamak i\u00e7in <code>EventEmitter<\/code> s\u0131n\u0131f\u0131n\u0131 sa\u011flar. Bu, Observer desenine daha yak\u0131n olsa da, bir i\u015flem i\u00e7inde olaylar\u0131 yay\u0131nlama ve dinleme mekanizmas\u0131 sa\u011flar.<\/p>\n<h5><code>events<\/code> Mod\u00fcl\u00fc ve <code>EventEmitter<\/code> S\u0131n\u0131f\u0131<\/h5>\n<p><code>EventEmitter<\/code>, adland\u0131r\u0131lm\u0131\u015f olaylar\u0131 dinleyebilen ve bu olaylar\u0131 tetikleyebilen nesneler olu\u015fturman\u0131za olanak tan\u0131r.<\/p>\n<p>*   <code>on(eventName, listener)<\/code>: Belirli bir olaya bir dinleyici (callback fonksiyonu) kaydeder. Olay her tetiklendi\u011finde dinleyici \u00e7al\u0131\u015f\u0131r.<br \/>\n*   <code>emit(eventName, [...args])<\/code>: Belirli bir olay\u0131 tetikler ve kay\u0131tl\u0131 t\u00fcm dinleyicileri \u00e7a\u011f\u0131r\u0131r. <code>args<\/code> ile dinleyicilere veri g\u00f6nderebilirsiniz.<br \/>\n*   <code>once(eventName, listener)<\/code>: Belirli bir olaya bir dinleyici kaydeder, ancak bu dinleyici yaln\u0131zca olay\u0131n ilk tetiklenmesinde \u00e7al\u0131\u015f\u0131r ve sonra otomatik olarak kald\u0131r\u0131l\u0131r.<br \/>\n*   <code>removeListener(eventName, listener)<\/code>: Belirli bir olaya kay\u0131tl\u0131 bir dinleyiciyi kald\u0131r\u0131r.<br \/>\n*   <code>removeAllListeners([eventName])<\/code>: Belirli bir olaya kay\u0131tl\u0131 t\u00fcm dinleyicileri kald\u0131r\u0131r. E\u011fer <code>eventName<\/code> belirtilmezse, t\u00fcm olaylara kay\u0131tl\u0131 t\u00fcm dinleyicileri kald\u0131r\u0131r.<\/p>\n<pre><code class=\"language-javascript\">const EventEmitter = require('events');\n\n\/\/ Yeni bir olay yay\u0131c\u0131 \u00f6rne\u011fi olu\u015ftur\nconst myEmitter = new EventEmitter();\n\n\/\/ 'kullaniciKayitOldu' olay\u0131na abone ol (dinleyici ekle)\nmyEmitter.on('kullaniciKayitOldu', (kullaniciAdi, email) => {\n    console.log(<code>Yeni kullan\u0131c\u0131 kaydedildi: ${kullaniciAdi}, E-posta: ${email}<\/code>);\n    \/\/ E-posta g\u00f6nderme, veritaban\u0131 kayd\u0131 vb. i\u015flemler yap\u0131labilir.\n});\n\nmyEmitter.on('siparisOlusturuldu', (siparisId, urunler) => {\n    console.log(<code>Yeni sipari\u015f olu\u015fturuldu: ID ${siparisId}, \u00dcr\u00fcnler: ${urunler.join(', ')}<\/code>);\n    \/\/ Stok g\u00fcncelleme, kargo bildirimi vb. i\u015flemler yap\u0131labilir.\n});\n\n\/\/ 'hata' olay\u0131n\u0131 dinle (EventEmitter'\u0131n \u00f6zel bir olay\u0131d\u0131r, dinlenmezse hata f\u0131rlat\u0131r)\nmyEmitter.on('error', (err) => {\n    console.error('Bir hata olu\u015ftu:', err.message);\n});\n\n\/\/ 'kullaniciKayitOldu' olay\u0131n\u0131 tetikle (yay\u0131nla)\nmyEmitter.emit('kullaniciKayitOldu', 'ali_veli', 'ali@example.com');\nmyEmitter.emit('kullaniciKayitOldu', 'ayse_fatma', 'ayse@example.com');\n\n\/\/ 'siparisOlusturuldu' olay\u0131n\u0131 tetikle\nmyEmitter.emit('siparisOlusturuldu', 'ORD-001', ['Laptop', 'Mouse']);\n\n\/\/ Bir hata olay\u0131 tetikle\nmyEmitter.emit('error', new Error('Veritaban\u0131 ba\u011flant\u0131s\u0131 ba\u015far\u0131s\u0131z.'));<\/code><\/pre>\n<p><code>EventEmitter<\/code>, tek bir Node.js i\u015flemi i\u00e7indeki farkl\u0131 mod\u00fcller veya bile\u015fenler aras\u0131nda ileti\u015fimi sa\u011flamak i\u00e7in harikad\u0131r. Ancak, uygulaman\u0131z birden fazla Node.js i\u015flemi veya farkl\u0131 sunucular \u00fczerinde \u00e7al\u0131\u015f\u0131yorsa, <code>EventEmitter<\/code> yetersiz kal\u0131r. Bu durumda da\u011f\u0131t\u0131k Pub\/Sub \u00e7\u00f6z\u00fcmlerine ihtiyac\u0131n\u0131z olur.<\/p>\n<h4>\u00dc\u00e7\u00fcnc\u00fc Parti K\u00fct\u00fcphaneler<\/h4>\n<p>Yerel <code>EventEmitter<\/code>&#8216;\u0131n baz\u0131 s\u0131n\u0131rlamalar\u0131n\u0131 a\u015fmak i\u00e7in (\u00f6rne\u011fin, wildcard olaylar, \u00f6ncelikli dinleyiciler), <code>eventemitter2<\/code>, <code>mitt<\/code> veya <code>nanoevents<\/code> gibi k\u00fct\u00fcphaneler kullan\u0131labilir. Ancak bunlar da yine tek i\u015flem i\u00e7i \u00e7\u00f6z\u00fcmlerdir. Da\u011f\u0131t\u0131k sistemler i\u00e7in ise farkl\u0131 teknolojilere y\u00f6nelmek gerekir.<\/p>\n<h4>Da\u011f\u0131t\u0131k Sistemler \u0130\u00e7in \u00c7\u00f6z\u00fcmler<\/h4>\n<p>Da\u011f\u0131t\u0131k sistemlerde, farkl\u0131 sunucularda veya mikroservislerde \u00e7al\u0131\u015fan bile\u015fenlerin birbirleriyle Pub\/Sub deseni arac\u0131l\u0131\u011f\u0131yla ileti\u015fim kurmas\u0131 i\u00e7in harici bir mesaj arac\u0131s\u0131na ihtiya\u00e7 duyulur.<\/p>\n<h5>Redis Pub\/Sub<\/h5>\n<p>Redis, in-memory bir veri yap\u0131s\u0131 deposu olarak bilinir ve ayn\u0131 zamanda yerle\u015fik bir Publish\/Subscribe mekanizmas\u0131 sunar. Basitli\u011fi ve y\u00fcksek h\u0131z\u0131 sayesinde, \u00f6zellikle ger\u00e7ek zamanl\u0131 uygulamalarda ve anl\u0131k bildirim sistemlerinde s\u0131k\u00e7a tercih edilir.<\/p>\n<p><strong>Nas\u0131l \u00c7al\u0131\u015f\u0131r:<\/strong><br \/>\nRedis Pub\/Sub, <code>PUBLISH<\/code> ve <code>SUBSCRIBE<\/code> komutlar\u0131 \u00fczerine kuruludur. Bir istemci belirli bir kanala abone oldu\u011funda, o kanala g\u00f6nderilen t\u00fcm mesajlar\u0131 al\u0131r. Bir ba\u015fka istemci ayn\u0131 kanala mesaj yay\u0131nlad\u0131\u011f\u0131nda, bu mesaj abone olan t\u00fcm istemcilere iletilir.<\/p>\n<p><strong>Node.js ile Kullan\u0131m\u0131:<\/strong><br \/>\n<code>redis<\/code> veya <code>@redis\/client<\/code> k\u00fct\u00fcphanesi ile Redis Pub\/Sub kolayca kullan\u0131labilir.<\/p>\n<pre><code class=\"language-javascript\">\/\/ publisher.js\nconst { createClient } = require('redis');\n\nasync function runPublisher() {\n    const publisher = createClient();\n    await publisher.connect();\n    console.log('Publisher Redis\\'e ba\u011fland\u0131.');\n\n    setInterval(async () => {\n        const message = <code>Merhaba, saat: ${new Date().toLocaleTimeString()}<\/code>;\n        await publisher.publish('genel_kanal', message);\n        console.log(<code>Yay\u0131nc\u0131 mesaj g\u00f6nderdi: \"${message}\"<\/code>);\n    }, 2000); \/\/ Her 2 saniyede bir mesaj g\u00f6nder\n}\n\nrunPublisher();\n\n\/\/ subscriber.js\nconst { createClient } = require('redis');\n\nasync function runSubscriber() {\n    const subscriber = createClient();\n    await subscriber.connect();\n    console.log('Subscriber Redis\\'e ba\u011fland\u0131.');\n\n    await subscriber.subscribe('genel_kanal', (message) => {\n        console.log(<code>Abone mesaj ald\u0131: \"${message}\"<\/code>);\n    });\n\n    console.log('Abone \"genel_kanal\"a abone oldu.');\n}\n\nrunSubscriber();<\/code><\/pre>\n<p><strong>Avantajlar\u0131:<\/strong><br \/>\n*   <strong>H\u0131z:<\/strong> Bellek i\u00e7i \u00e7al\u0131\u015fmas\u0131 sayesinde \u00e7ok h\u0131zl\u0131d\u0131r.<br \/>\n*   <strong>Basitlik:<\/strong> Kurulumu ve kullan\u0131m\u0131 kolayd\u0131r.<br \/>\n*   <strong>Ger\u00e7ek Zamanl\u0131:<\/strong> D\u00fc\u015f\u00fck gecikme s\u00fcresi ile ger\u00e7ek zamanl\u0131 uygulamalar i\u00e7in idealdir.<\/p>\n<p><strong>Dezavantajlar\u0131:<\/strong><br \/>\n*   <strong>Mesaj Kal\u0131c\u0131l\u0131\u011f\u0131 Yok:<\/strong> Abone olmayan istemcilere mesajlar teslim edilmez. Abone olan bir istemci \u00e7evrimd\u0131\u015f\u0131 ise, \u00e7evrimd\u0131\u015f\u0131 oldu\u011fu s\u00fcre boyunca yay\u0131nlanan mesajlar\u0131 ka\u00e7\u0131r\u0131r.<br \/>\n*   <strong>Teslimat Garantisi Yok:<\/strong> Mesajlar\u0131n ba\u015far\u0131yla teslim edildi\u011fine dair bir garanti sunmaz (at-most-once teslimat).<\/p>\n<h5>RabbitMQ<\/h5>\n<p>RabbitMQ, Advanced Message Queuing Protocol (AMQP) uygulayan pop\u00fcler bir mesaj brokeridir. Geli\u015fmi\u015f y\u00f6nlendirme yetenekleri, mesaj kal\u0131c\u0131l\u0131\u011f\u0131 ve teslimat garantileri sunar, bu da onu kurumsal d\u00fczeydeki uygulamalar i\u00e7in g\u00fc\u00e7l\u00fc bir se\u00e7enek haline getirir.<\/p>\n<p><strong>Nas\u0131l \u00c7al\u0131\u015f\u0131r:<\/strong><br \/>\nRabbitMQ&#8217;da yay\u0131nc\u0131lar do\u011frudan kuyruklara de\u011fil, &#8220;exchange&#8221;lere mesaj g\u00f6nderir. Exchange&#8217;ler, gelen mesajlar\u0131 &#8220;binding&#8221; kurallar\u0131na g\u00f6re bir veya daha fazla kuyru\u011fa y\u00f6nlendirir. Aboneler (t\u00fcketiciler) ise bu kuyruklardan mesajlar\u0131 \u00e7eker. Bu model, daha karma\u015f\u0131k y\u00f6nlendirme senaryolar\u0131na olanak tan\u0131r (direct, fanout, topic, headers exchange).<\/p>\n<p><strong>Node.js ile Kullan\u0131m\u0131:<\/strong><br \/>\n<code>amqplib<\/code> k\u00fct\u00fcphanesi, Node.js uygulamalar\u0131nda RabbitMQ ile etkile\u015fim kurmak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-javascript\">\/\/ publisher.js\nconst amqp = require('amqplib');\n\nasync function runPublisher() {\n    try {\n        const connection = await amqp.connect('amqp:\/\/localhost');\n        const channel = await connection.createChannel();\n\n        const exchangeName = 'log_exchange';\n        await channel.assertExchange(exchangeName, 'fanout', { durable: false }); \/\/ fanout: t\u00fcm kuyruklara g\u00f6nder\n\n        setInterval(() => {\n            const message = <code>Log mesaj\u0131: ${new Date().toLocaleTimeString()}<\/code>;\n            channel.publish(exchangeName, '', Buffer.from(message)); \/\/ routingKey bo\u015f\n            console.log(<code>Yay\u0131nc\u0131 mesaj g\u00f6nderdi: \"${message}\"<\/code>);\n        }, 3000);\n\n        \/\/ process.on('beforeExit', () => {\n        \/\/     console.log('Kanal ve ba\u011flant\u0131 kapat\u0131l\u0131yor...');\n        \/\/     channel.close();\n        \/\/     connection.close();\n        \/\/ });\n\n    } catch (error) {\n        console.error('RabbitMQ Publisher Hatas\u0131:', error.message);\n    }\n}\n\nrunPublisher();\n\n\/\/ subscriber.js\nconst amqp = require('amqplib');\n\nasync function runSubscriber() {\n    try {\n        const connection = await amqp.connect('amqp:\/\/localhost');\n        const channel = await connection.createChannel();\n\n        const exchangeName = 'log_exchange';\n        await channel.assertExchange(exchangeName, 'fanout', { durable: false });\n\n        const q = await channel.assertQueue('', { exclusive: true }); \/\/ Ge\u00e7ici, benzersiz bir kuyruk olu\u015ftur\n        console.log(<code>Abone, '${q.queue}' kuyru\u011funu bekliyor.<\/code>);\n\n        await channel.bindQueue(q.queue, exchangeName, ''); \/\/ Kuyru\u011fu exchange'e ba\u011fla\n\n        channel.consume(q.queue, (msg) => {\n            if (msg.content) {\n                console.log(<code>Abone mesaj ald\u0131: \"${msg.content.toString()}\"<\/code>);\n                \/\/ Mesaj i\u015flendikten sonra ACK g\u00f6nder\n                channel.ack(msg);\n            }\n        }, { noAck: false }); \/\/ noAck: false, mesaj\u0131 i\u015fledikten sonra onay g\u00f6ndermemizi sa\u011flar\n\n    } catch (error) {\n        console.error('RabbitMQ Subscriber Hatas\u0131:', error.message);\n    }\n}\n\nrunSubscriber();<\/code><\/pre>\n<p><strong>Avantajlar\u0131:<\/strong><br \/>\n*   <strong>Teslimat Garantisi:<\/strong> Mesajlar\u0131n kaybolmamas\u0131n\u0131 sa\u011flayan kal\u0131c\u0131l\u0131k ve onay mekanizmalar\u0131 sunar (at-least-once teslimat).<br \/>\n*   <strong>Geli\u015fmi\u015f Y\u00f6nlendirme:<\/strong> Farkl\u0131 exchange t\u00fcrleri ile karma\u015f\u0131k mesaj y\u00f6nlendirme senaryolar\u0131na izin verir.<br \/>\n*   <strong>Esneklik:<\/strong> Kuyruklar, de\u011fi\u015fimler ve ba\u011flamalar ile esnek bir mimari sa\u011flar.<\/p>\n<p><strong>Dezavantajlar\u0131:<\/strong><br \/>\n*   <strong>Karma\u015f\u0131kl\u0131k:<\/strong> Kurulumu ve y\u00f6netimi Redis&#8217;e g\u00f6re daha karma\u015f\u0131kt\u0131r.<br \/>\n*   <strong>Performans:<\/strong> Redis kadar saf h\u0131z sunmayabilir, ancak \u00e7o\u011fu uygulama i\u00e7in yeterince h\u0131zl\u0131d\u0131r.<\/p>\n<h5>Apache Kafka<\/h5>\n<p>Apache Kafka, y\u00fcksek performansl\u0131, da\u011f\u0131t\u0131k bir ak\u0131\u015f platformudur. B\u00fcy\u00fck veri ak\u0131\u015flar\u0131n\u0131 i\u015flemek, ger\u00e7ek zamanl\u0131 analiz yapmak ve da\u011f\u0131t\u0131k sistemler aras\u0131nda g\u00fcvenilir mesajla\u015fma sa\u011flamak i\u00e7in tasarlanm\u0131\u015ft\u0131r.<\/p>\n<p><strong>Nas\u0131l \u00c7al\u0131\u015f\u0131r:<\/strong><br \/>\nKafka&#8217;da mesajlar &#8220;topic&#8221;lere (konulara) yaz\u0131l\u0131r. Her topic, &#8220;partition&#8221;lara (b\u00f6l\u00fcmlere) ayr\u0131l\u0131r ve mesajlar bu b\u00f6l\u00fcmlere eklenir. Yay\u0131nc\u0131lar (producer), mesajlar\u0131 belirli topic&#8217;lere g\u00f6nderir. Aboneler (consumer), bir topic&#8217;teki bir veya daha fazla b\u00f6l\u00fcmden mesajlar\u0131 okur. Kafka, mesajlar\u0131n kal\u0131c\u0131l\u0131\u011f\u0131n\u0131 diskte sa\u011flar ve t\u00fcketici gruplar\u0131 sayesinde \u00f6l\u00e7eklenebilir t\u00fcketimi destekler.<\/p>\n<p><strong>Node.js ile Kullan\u0131m\u0131:<\/strong><br \/>\n<code>kafkajs<\/code> veya <code>node-rdkafka<\/code> gibi k\u00fct\u00fcphaneler Node.js&#8217;te Kafka ile etkile\u015fim kurmak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-javascript\">\/\/ producer.js\nconst { Kafka } = require('kafkajs');\n\nasync function runProducer() {\n    const kafka = new Kafka({\n        clientId: 'my-app',\n        brokers: ['localhost:9092'] \/\/ Kafka broker adresleri\n    });\n\n    const producer = kafka.producer();\n    await producer.connect();\n    console.log('Producer Kafka\\'ya ba\u011fland\u0131.');\n\n    setInterval(async () => {\n        const message = <code>Kafka mesaj\u0131: ${new Date().toLocaleTimeString()}<\/code>;\n        await producer.send({\n            topic: 'my-topic',\n            messages: [{ value: message }],\n        });\n        console.log(<code>Producer mesaj g\u00f6nderdi: \"${message}\"<\/code>);\n    }, 4000);\n\n    \/\/ process.on('beforeExit', async () => {\n    \/\/     console.log('Producer ba\u011flant\u0131s\u0131 kapat\u0131l\u0131yor...');\n    \/\/     await producer.disconnect();\n    \/\/ });\n}\n\nrunProducer();\n\n\/\/ consumer.js\nconst { Kafka } = require('kafkajs');\n\nasync function runConsumer() {\n    const kafka = new Kafka({\n        clientId: 'my-app',\n        brokers: ['localhost:9092']\n    });\n\n    const consumer = kafka.consumer({ groupId: 'my-group' }); \/\/ T\u00fcketici grubu\n    await consumer.connect();\n    console.log('Consumer Kafka\\'ya ba\u011fland\u0131.');\n\n    await consumer.subscribe({ topic: 'my-topic', fromBeginning: true });\n\n    await consumer.run({\n        eachMessage: async ({ topic, partition, message }) => {\n            console.log({\n                value: message.value.toString(),\n                topic: topic,\n                partition: partition,\n            });\n        },\n    });\n\n    console.log('Consumer \"my-topic\"e abone oldu.');\n}\n\nrunConsumer();<\/code><\/pre>\n<p><strong>Avantajlar\u0131:<\/strong><br \/>\n*   <strong>Y\u00fcksek Throughput ve \u00d6l\u00e7eklenebilirlik:<\/strong> \u00c7ok y\u00fcksek hacimli mesajlar\u0131 i\u015fleyebilir ve yatay olarak \u00f6l\u00e7eklenebilir.<br \/>\n*   <strong>Veri Kal\u0131c\u0131l\u0131\u011f\u0131:<\/strong> Mesajlar\u0131 diskte belirli bir s\u00fcre boyunca saklar, bu da t\u00fcketicilerin ge\u00e7mi\u015f mesajlar\u0131 yeniden i\u015flemesine olanak tan\u0131r.<br \/>\n*   <strong>Hata Tolerans\u0131:<\/strong> Da\u011f\u0131t\u0131k yap\u0131s\u0131 sayesinde y\u00fcksek hata tolerans\u0131 sunar.<br \/>\n*   <strong>Ak\u0131\u015f \u0130\u015fleme:<\/strong> Ger\u00e7ek zamanl\u0131 veri ak\u0131\u015flar\u0131n\u0131 i\u015flemek i\u00e7in g\u00fc\u00e7l\u00fc yeteneklere sahiptir.<\/p>\n<p><strong>Dezavantajlar\u0131:<\/strong><br \/>\n*   <strong>Karma\u015f\u0131kl\u0131k:<\/strong> Kurulumu ve y\u00f6netimi di\u011ferlerine g\u00f6re daha karma\u015f\u0131kt\u0131r. Operasyonel y\u00fck\u00fc daha fazlad\u0131r.<br \/>\n*   <strong>Gecikme:<\/strong> Redis&#8217;e g\u00f6re daha y\u00fcksek gecikme s\u00fcreleri olabilir, ancak bu genellikle kabul edilebilir seviyededir.<\/p>\n<h5>Di\u011ferleri<\/h5>\n<p>Bulut sa\u011flay\u0131c\u0131lar\u0131 da kendi Pub\/Sub hizmetlerini sunar:<br \/>\n*   <strong>AWS SNS (Simple Notification Service) &#038; SQS (Simple Queue Service):<\/strong> SNS bir Pub\/Sub hizmeti iken, SQS bir mesaj kuyru\u011fu hizmetidir. Genellikle birlikte kullan\u0131l\u0131rlar.<br \/>\n*   <strong>Google Cloud Pub\/Sub:<\/strong> Google&#8217;\u0131n y\u00fcksek \u00f6l\u00e7eklenebilir ve k\u00fcresel Pub\/Sub hizmetidir.<br \/>\n*   <strong>Azure Service Bus:<\/strong> Microsoft Azure&#8217;\u0131n mesajla\u015fma hizmetidir, hem kuyruk hem de konular\u0131 destekler.<\/p>\n<p>Bu hizmetler, y\u00f6netilen \u00e7\u00f6z\u00fcmler oldu\u011fu i\u00e7in altyap\u0131 y\u00f6netimi y\u00fck\u00fcn\u00fc azalt\u0131r ve bulut ortamlar\u0131nda kolayca entegre edilebilir.<\/p>\n<h3>Kullan\u0131m Senaryolar\u0131<\/h3>\n<p>Publish\/Subscribe deseni, bir\u00e7ok farkl\u0131 senaryoda de\u011fer katar:<\/p>\n<p>*   <strong>Ger\u00e7ek Zamanl\u0131 Uygulamalar:<\/strong> Sohbet uygulamalar\u0131, canl\u0131 bildirimler, oyunlar veya finansal veri ak\u0131\u015flar\u0131 gibi anl\u0131k g\u00fcncellemeler gerektiren uygulamalarda kullan\u0131l\u0131r. (\u00d6rn: WebSocket ile entegre Redis Pub\/Sub)<br \/>\n*   <strong>Mikroservis Mimarileri Aras\u0131 \u0130leti\u015fim:<\/strong> Mikroservislerin birbirleriyle gev\u015fek ba\u011fl\u0131 bir \u015fekilde ileti\u015fim kurmas\u0131n\u0131 sa\u011flar. Bir servis bir olay\u0131 yay\u0131nlar, di\u011fer servisler bu olaya tepki verir. (\u00d6rn: RabbitMQ, Kafka)<br \/>\n*   <strong>Arka Plan \u0130\u015flemleri ve Asenkron G\u00f6revler:<\/strong> Kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc engellemeden uzun s\u00fcren veya yo\u011fun kaynak gerektiren i\u015flemleri arka plana atmak i\u00e7in kullan\u0131l\u0131r (\u00f6rn: e-posta g\u00f6nderme, resim i\u015fleme, rapor olu\u015fturma).<br \/>\n*   <strong>\u00d6nbellek Ge\u00e7ersiz K\u0131lma:<\/strong> Bir veri de\u011fi\u015fti\u011finde, ilgili \u00f6nbellekleri ge\u00e7ersiz k\u0131lmak i\u00e7in bir olay yay\u0131nlanabilir.<br \/>\n*   <strong>Loglama ve \u0130zleme:<\/strong> Uygulama olaylar\u0131n\u0131 veya hatalar\u0131n\u0131 merkezi bir loglama veya izleme sistemine g\u00f6ndermek i\u00e7in kullan\u0131labilir.<br \/>\n*   <strong>Veri Senkronizasyonu:<\/strong> Da\u011f\u0131t\u0131k veritabanlar\u0131 veya servisler aras\u0131nda veri de\u011fi\u015fikliklerini senkronize etmek i\u00e7in kullan\u0131l\u0131r.<\/p>\n<h3>Avantajlar\u0131<\/h3>\n<p>Publish\/Subscribe deseninin sa\u011flad\u0131\u011f\u0131 temel avantajlar \u015funlard\u0131r:<\/p>\n<p>*   <strong>Gev\u015fek Ba\u011fl\u0131l\u0131k:<\/strong> Yay\u0131nc\u0131lar ve aboneler birbirlerinin varl\u0131\u011f\u0131ndan haberdar de\u011fildir. Bu, bile\u015fenlerin ba\u011f\u0131ms\u0131z olarak geli\u015ftirilmesini, test edilmesini ve da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar.<br \/>\n*   <strong>\u00d6l\u00e7eklenebilirlik:<\/strong> Sistemin her iki taraf\u0131 da ba\u011f\u0131ms\u0131z olarak \u00f6l\u00e7eklenebilir. Daha fazla yay\u0131nc\u0131 veya abone eklenebilir veya \u00e7\u0131kar\u0131labilir, bu da sistemin genel performans\u0131n\u0131 etkilemez.<br \/>\n*   <strong>Esneklik ve Geni\u015fletilebilirlik:<\/strong> Yeni \u00f6zellikler veya bile\u015fenler eklemek kolayd\u0131r. Mevcut kodda b\u00fcy\u00fck de\u011fi\u015fiklikler yapmadan yeni aboneler ekleyerek sisteme yeni i\u015flevler kazand\u0131r\u0131labilir.<br \/>\n*   <strong>Performans:<\/strong> Asenkron do\u011fas\u0131 sayesinde, yay\u0131nc\u0131lar mesaj\u0131 g\u00f6nderdikten sonra beklemek zorunda kalmazlar, bu da genel sistem yan\u0131t s\u00fcresini iyile\u015ftirir.<br \/>\n*   <strong>Mod\u00fclerlik:<\/strong> Sistem daha k\u00fc\u00e7\u00fck, y\u00f6netilebilir mod\u00fcllere ayr\u0131l\u0131r, bu da kodun anla\u015f\u0131labilirli\u011fini ve bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r.<br \/>\n*   <strong>Hata \u0130zolasyonu:<\/strong> Bir abonenin hata vermesi, di\u011fer aboneleri veya yay\u0131nc\u0131y\u0131 do\u011frudan etkilemez (broker&#8217;\u0131n sa\u011flaml\u0131\u011f\u0131na ba\u011fl\u0131 olarak).<\/p>\n<h3>Dezavantajlar\u0131 ve Zorluklar<\/h3>\n<p>Avantajlar\u0131n\u0131n yan\u0131 s\u0131ra, Publish\/Subscribe deseninin baz\u0131 dezavantajlar\u0131 ve beraberinde getirdi\u011fi zorluklar da vard\u0131r:<\/p>\n<p>*   <strong>Mesaj Teslimat Garantisi:<\/strong> Farkl\u0131 broker&#8217;lar farkl\u0131 teslimat garantileri sunar (at-most-once, at-least-once, exactly-once). Uygulaman\u0131z\u0131n gereksinimlerine g\u00f6re do\u011fru broker&#8217;\u0131 se\u00e7mek \u00f6nemlidir. Redis Pub\/Sub&#8217;da mesajlar kaybolabilirken, RabbitMQ ve Kafka daha g\u00fc\u00e7l\u00fc garantiler sunar.<br \/>\n*   <strong>Mesaj S\u0131ras\u0131:<\/strong> Mesajlar\u0131n do\u011fru s\u0131rada i\u015flenmesi baz\u0131 senaryolarda kritik olabilir. Da\u011f\u0131t\u0131k sistemlerde bu, \u00f6zellikle ayn\u0131 konuya birden fazla t\u00fcketici abone oldu\u011funda zorla\u015fabilir. Kafka, b\u00f6l\u00fcm baz\u0131nda s\u0131ra garantisi sunar.<br \/>\n*   <strong>Hata Y\u00f6netimi ve Yeniden Deneme Mekanizmalar\u0131:<\/strong> Bir abonenin mesaj\u0131 i\u015flerken hata vermesi durumunda ne yap\u0131laca\u011f\u0131 (yeniden deneme, \u00f6l\u00fc-harf kuyruklar\u0131) iyi d\u00fc\u015f\u00fcn\u00fclmelidir.<br \/>\n*   <strong>Debugging Zorluklar\u0131:<\/strong> Yay\u0131nc\u0131 ve abone aras\u0131nda do\u011frudan ba\u011flant\u0131 olmad\u0131\u011f\u0131 i\u00e7in, bir sorunun kayna\u011f\u0131n\u0131 bulmak ve mesaj ak\u0131\u015f\u0131n\u0131 izlemek daha zor olabilir.<br \/>\n*   <strong>Operasyonel Karma\u015f\u0131kl\u0131k:<\/strong> \u00d6zellikle RabbitMQ veya Kafka gibi da\u011f\u0131t\u0131k mesaj broker&#8217;lar\u0131, kurulum, yap\u0131land\u0131rma, izleme ve bak\u0131m a\u00e7\u0131s\u0131ndan operasyonel bir y\u00fck getirir.<br \/>\n*   <strong>Mesaj \u015eemas\u0131 Y\u00f6netimi:<\/strong> Yay\u0131nlanan mesajlar\u0131n tutarl\u0131 bir \u015femaya sahip olmas\u0131 \u00f6nemlidir. Aksi takdirde, abonelerin mesajlar\u0131 do\u011fru bir \u015fekilde yorumlamas\u0131 zorla\u015f\u0131r.<\/p>\n<h3>En \u0130yi Uygulamalar<\/h3>\n<p>Publish\/Subscribe desenini etkin bir \u015fekilde kullanmak i\u00e7in baz\u0131 en iyi uygulamalar \u015funlard\u0131r:<\/p>\n<p>*   <strong>Anlaml\u0131 Konu \u0130simleri:<\/strong> Konu isimleri, yay\u0131nlanan mesaj\u0131n amac\u0131n\u0131 ve i\u00e7eri\u011fini a\u00e7\u0131k\u00e7a belirtmelidir. \u00d6rne\u011fin, <code>user.created<\/code>, <code>order.processed<\/code>, <code>payment.failed<\/code>.<br \/>\n*   <strong>Mesaj \u015eemas\u0131 Tan\u0131mlama:<\/strong> Yay\u0131nlanan mesajlar\u0131n yap\u0131s\u0131n\u0131 (\u015femas\u0131n\u0131) a\u00e7\u0131k\u00e7a tan\u0131mlay\u0131n ve dok\u00fcmante edin. JSON Schema veya Avro gibi ara\u00e7lar kullan\u0131labilir. Bu, abonelerin mesajlar\u0131 g\u00fcvenle t\u00fcketmesini sa\u011flar.<br \/>\n*   <strong>Hata \u0130\u015fleme ve Dayan\u0131kl\u0131l\u0131k:<\/strong> Abonelerin mesajlar\u0131 i\u015flerken olu\u015fabilecek hatalar\u0131 y\u00f6netti\u011finden emin olun. Yeniden deneme mekanizmalar\u0131, \u00f6l\u00fc-harf kuyruklar\u0131 (dead-letter queues) ve mesaj onaylar\u0131 (acknowledgements) kullan\u0131lmal\u0131d\u0131r.<br \/>\n*   <strong>\u0130zleme ve Loglama:<\/strong> Mesajlar\u0131n ak\u0131\u015f\u0131n\u0131, kuyruk boyutlar\u0131n\u0131, t\u00fcketici gecikmelerini ve hata oranlar\u0131n\u0131 izlemek i\u00e7in kapsaml\u0131 loglama ve izleme sistemleri kurun.<br \/>\n*   <strong>G\u00fcvenlik:<\/strong> Hassas veriler i\u00e7eren mesajlar i\u00e7in \u015fifreleme ve kimlik do\u011frulama\/yetkilendirme mekanizmalar\u0131n\u0131 uygulay\u0131n.<br \/>\n*   <strong>Idempotency:<\/strong> Abonelerin ayn\u0131 mesaj\u0131 birden fazla kez almas\u0131 durumunda bile do\u011fru sonu\u00e7lar \u00fcretecek \u015fekilde i\u015f mant\u0131\u011f\u0131n\u0131 tasarlay\u0131n. (at-least-once teslimat garantisi olan sistemlerde \u00f6nemlidir).<br \/>\n*   <strong>Mesaj B\u00fcy\u00fckl\u00fc\u011f\u00fc:<\/strong> \u00c7ok b\u00fcy\u00fck mesajlardan ka\u00e7\u0131n\u0131n. Gerekirse, mesajda sadece referanslar\u0131 g\u00f6nderip, as\u0131l veriyi ba\u015fka bir yerden (veritaban\u0131, depolama) \u00e7ekin.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Publish\/Subscribe deseni, Node.js uygulamalar\u0131nda, \u00f6zellikle da\u011f\u0131t\u0131k ve olay odakl\u0131 sistemlerde ileti\u015fimi basitle\u015ftiren, esnek ve \u00f6l\u00e7eklenebilir bir yakla\u015f\u0131md\u0131r. Node.js&#8217;in yerle\u015fik <code>EventEmitter<\/code>&#8216;\u0131 tek bir i\u015flem i\u00e7indeki basit senaryolar i\u00e7in yeterli olsa da, mikroservisler ve ger\u00e7ek zamanl\u0131 uygulamalar gibi daha karma\u015f\u0131k ve da\u011f\u0131t\u0131k senaryolarda Redis, RabbitMQ veya Apache Kafka gibi harici mesaj broker&#8217;lar\u0131 vazge\u00e7ilmezdir.<\/p>\n<p>Bu desenin sa\u011flad\u0131\u011f\u0131 gev\u015fek ba\u011fl\u0131l\u0131k, sistemlerin daha mod\u00fcler, y\u00f6netilebilir ve geni\u015fletilebilir olmas\u0131n\u0131 sa\u011flar. Ancak, mesaj teslimat garantileri, s\u0131ralama ve hata y\u00f6netimi gibi zorluklar g\u00f6z \u00f6n\u00fcnde bulundurulmal\u0131 ve uygulaman\u0131n gereksinimlerine en uygun ara\u00e7 se\u00e7imi yap\u0131lmal\u0131d\u0131r. Do\u011fru uyguland\u0131\u011f\u0131nda, Publish\/Subscribe deseni, modern Node.js uygulamalar\u0131n\u0131n performans\u0131n\u0131, dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 ve \u00f6l\u00e7eklenebilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir. Gelecekte, bulut tabanl\u0131 y\u00f6netilen Pub\/Sub hizmetlerinin yayg\u0131nla\u015fmas\u0131yla birlikte, bu desenin kullan\u0131m\u0131 daha da kolayla\u015facak ve daha geni\u015f bir uygulama yelpazesinde standart hale gelecektir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te\nPublish\/Subscribe (Pub\/Sub) deseni, modern yaz\u0131l\u0131m mimarilerinde, \u00f6zellikle da\u011f\u0131t\u0131k sis","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":[136],"tags":[],"class_list":{"0":"post-37550","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-node-js","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>Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#039;te - 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\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#039;te\" \/>\n<meta property=\"og:description\" content=\"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#039;te Publish\/Subscribe (Pub\/Sub) deseni, modern yaz\u0131l\u0131m mimarilerinde, \u00f6zellikle da\u011f\u0131t\u0131k sis\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-08T17:41:08+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=\"19 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te\",\"datePublished\":\"2026-01-08T17:41:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\"},\"wordCount\":3113,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Node.js\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\",\"name\":\"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js'te - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-01-08T17:41:08+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te\"}]},{\"@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":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js'te - 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\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/","og_locale":"tr_TR","og_type":"article","og_title":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js'te","og_description":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js'te Publish\/Subscribe (Pub\/Sub) deseni, modern yaz\u0131l\u0131m mimarilerinde, \u00f6zellikle da\u011f\u0131t\u0131k sis","og_url":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-01-08T17:41:08+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"19 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te","datePublished":"2026-01-08T17:41:08+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/"},"wordCount":3113,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Node.js"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/","url":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/","name":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js'te - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-01-08T17:41:08+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/publish-subscribe-yayinla-abone-ol-deseni-node-jste\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Publish\/Subscribe (Yay\u0131nla\/Abone Ol) Deseni Node.js&#8217;te"}]},{"@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\/37550","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=37550"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37550\/revisions"}],"predecessor-version":[{"id":37551,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37550\/revisions\/37551"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=37550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=37550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=37550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}