{"id":32944,"date":"2025-10-27T16:33:47","date_gmt":"2025-10-27T13:33:47","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/"},"modified":"2025-10-27T16:33:47","modified_gmt":"2025-10-27T13:33:47","slug":"java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/","title":{"rendered":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber"},"content":{"rendered":"<p><body><\/p>\n<style>\n        \/* Temel stil tan\u0131mlamalar\u0131 *\/\n        body {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            line-height: 1.7;\n            color: #333;\n            max-width: 960px;\n            margin: 0 auto;\n            padding: 20px;\n            background-color: #f9fbfd;\n        }\n        h2 {\n            color: #2c3e50;\n            margin-top: 40px;\n            padding-bottom: 10px;\n            border-bottom: 2px solid #3498db;\n            font-size: 1.8em;\n            font-weight: 600;\n        }\n        h3 {\n            color: #34495e;\n            margin-top: 30px;\n            font-size: 1.4em;\n            font-weight: 500;\n        }\n        p {\n            margin-bottom: 15px;\n            text-align: justify;\n        }\n        ul, ol {\n            margin-bottom: 15px;\n            padding-left: 25px;\n        }\n        li {\n            margin-bottom: 8px;\n        }\n        pre {\n            background-color: #2d2d2d; \/* Koyu tema *\/\n            color: #f8f8f2;\n            padding: 18px;\n            border-radius: 8px;\n            overflow-x: auto;\n            font-family: 'Fira Code', 'Cascadia Code', 'Consolas', monospace;\n            font-size: 0.9em;\n            margin-bottom: 20px;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n        }\n        code {\n            font-family: 'Fira Code', 'Cascadia Code', 'Consolas', monospace;\n            background-color: #e8e8e8;\n            padding: 2px 4px;\n            border-radius: 4px;\n            color: #c7254e;\n        }\n        pre code {\n            background-color: transparent;\n            color: #f8f8f2;\n            padding: 0;\n        }\n        table {\n            width: 100%;\n            border-collapse: collapse;\n            margin-bottom: 25px;\n            background-color: #ffffff;\n            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.08);\n        }\n        th, td {\n            border: 1px solid #ddd;\n            padding: 12px;\n            text-align: left;\n        }\n        th {\n            background-color: #eef4f8;\n            color: #34495e;\n            font-weight: 600;\n        }\n        tr:nth-child(even) {\n            background-color: #f5f5f5;\n        }\n        .interactive-tip {\n            background-color: #e0f2f7;\n            border-left: 6px solid #2196f3;\n            padding: 20px;\n            margin: 30px 0;\n            font-style: italic;\n            color: #0d47a1;\n            border-radius: 8px;\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n        }\n        .warning {\n            background-color: #fff3cd;\n            border-left: 6px solid #ffc107;\n            padding: 20px;\n            margin: 30px 0;\n            color: #664d03;\n            border-radius: 8px;\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n        }\n        .success {\n            background-color: #d1e7dd;\n            border-left: 6px solid #198754;\n            padding: 20px;\n            margin: 30px 0;\n            color: #0f5132;\n            border-radius: 8px;\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n        }<\/p>\n<p>        \/* Mobil uyumlu stil tan\u0131mlamalar\u0131 *\/\n        @media (max-width: 768px) {\n            body {\n                padding: 15px;\n            }\n            h2 {\n                font-size: 1.6em;\n            }\n            h3 {\n                font-size: 1.3em;\n            }\n            pre {\n                padding: 15px;\n            }\n            table, th, td {\n                font-size: 0.9em;\n                display: block; \/* Table elements become block for better stacking *\/\n                width: 100%;\n                box-sizing: border-box; \/* Include padding\/border in element's total width\/height *\/\n            }\n            th, td {\n                text-align: left;\n                padding: 10px;\n            }\n            th {\n                background-color: #eef4f8;\n            }\n            td::before { \/* Add label before content on small screens *\/\n                content: attr(data-label);\n                font-weight: bold;\n                display: inline-block;\n                width: 80px; \/* Adjust as needed *\/\n                margin-right: 10px;\n            }\n        }\n        @media (max-width: 480px) {\n            body {\n                padding: 10px;\n            }\n            h2 {\n                font-size: 1.4em;\n            }\n            h3 {\n                font-size: 1.1em;\n            }\n            .interactive-tip, .warning, .success {\n                padding: 15px;\n            }\n        }\n    <\/style>\n<p>Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.<\/p>\n<p>Geleneksel mimarilerde, bir bile\u015fenin ba\u015fka bir bile\u015fenden veri veya hizmet istedi\u011fi senkronize bir ileti\u015fim modeli hakimdir. Bu yakla\u015f\u0131m, basit sistemler i\u00e7in yeterli olsa da, mikroservislerin yayg\u0131nla\u015fmas\u0131 ve karma\u015f\u0131k i\u015f s\u00fcre\u00e7lerinin y\u00f6netimi s\u00f6z konusu oldu\u011funda baz\u0131 ciddi darbo\u011fazlar yaratabilir. Geleneksel yakla\u015f\u0131mlar genellikle servisler aras\u0131nda s\u0131k\u0131 bir ba\u011f\u0131ml\u0131l\u0131k (tight coupling) olu\u015fturur, bu da bir serviste yap\u0131lan de\u011fi\u015fikli\u011fin di\u011fer servisleri etkileme riskini art\u0131r\u0131r ve sistemin genel olarak daha k\u0131r\u0131lgan olmas\u0131na yol a\u00e7ar. \u0130\u015fte tam bu noktada Olay Odakl\u0131 Mimari (EDA) devreye girer. EDA, sistem bile\u015fenlerinin &#8220;olaylar&#8221; arac\u0131l\u0131\u011f\u0131yla asenkron olarak ileti\u015fim kurdu\u011fu bir tasar\u0131m paradigmas\u0131d\u0131r. Bir bile\u015fen bir olay\u0131 (&#8220;\u00fcr\u00fcn sipari\u015f edildi&#8221;, &#8220;kullan\u0131c\u0131 kaydoldu&#8221;) yay\u0131nlad\u0131\u011f\u0131nda, bu olaydan haberdar olmak isteyen di\u011fer bile\u015fenler (t\u00fcketiciler) bu olay\u0131 dinler ve kendi i\u015f mant\u0131klar\u0131n\u0131 buna g\u00f6re y\u00fcr\u00fct\u00fcrler. Bu model, gev\u015fek ba\u011fl\u0131 (loosely coupled) sistemler olu\u015fturarak bir bile\u015fenin di\u011ferini do\u011frudan bilme ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131r. Yani, sipari\u015f hizmeti bir sipari\u015f olu\u015fturdu\u011funda, bunu do\u011frudan \u00f6deme hizmetine veya envanter hizmetine g\u00f6ndermek yerine, bir &#8220;Sipari\u015fOlu\u015fturuldu&#8221; olay\u0131 yay\u0131nlar. \u00d6deme hizmeti ve envanter hizmeti gibi ilgili di\u011fer hizmetler bu olay\u0131 al\u0131r ve kendi operasyonlar\u0131n\u0131 (\u00f6rne\u011fin, \u00f6deme alma veya stok g\u00fcncelleme) ba\u011f\u0131ms\u0131z olarak ger\u00e7ekle\u015ftirirler.<\/p>\n<p>EDA&#8217;n\u0131n sa\u011flad\u0131\u011f\u0131 en b\u00fcy\u00fck avantajlardan biri, sistemlerin \u00f6l\u00e7eklenebilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rmas\u0131d\u0131r. Senkronize \u00e7a\u011fr\u0131lar yerine asenkron mesajla\u015fma sayesinde, her servis kendi h\u0131z\u0131nda \u00e7al\u0131\u015fabilir ve talepleri i\u015fleyebilir. Bir servisin y\u00fck\u00fc artt\u0131\u011f\u0131nda, sadece o servisin \u00f6l\u00e7e\u011fi b\u00fcy\u00fct\u00fclerek genel sistem performans\u0131 korunabilir. Bu durum, \u00f6zellikle y\u00fcksek trafikli uygulamalar ve b\u00fcy\u00fcme potansiyeli olan platformlar i\u00e7in hayati \u00f6neme sahiptir. Ayr\u0131ca, EDA sistemlerde esnekli\u011fi ve dayan\u0131kl\u0131l\u0131\u011f\u0131 da art\u0131r\u0131r. Bir servis ge\u00e7ici olarak kullan\u0131lamaz hale gelse bile, olaylar mesaj kuyruklar\u0131nda bekleyebilir ve servis tekrar \u00e7evrimi\u00e7i oldu\u011funda i\u015flenmeye devam edebilir. Bu durum, hata tolerans\u0131n\u0131 art\u0131r\u0131r ve sistemin genel olarak daha sa\u011flam olmas\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, bir e-ticaret uygulamas\u0131nda, kullan\u0131c\u0131 yeni bir \u00fcr\u00fcn sipari\u015f etti\u011finde, bu olay\u0131 i\u015fleyen birka\u00e7 farkl\u0131 servis olabilir: sipari\u015f onaylama, envanteri g\u00fcncelleme, lojistik planlama, m\u00fc\u015fteri bildirimleri g\u00f6nderme. E\u011fer bu servislerden biri anl\u0131k olarak me\u015fgulse veya bir hata veriyorsa, olay bir kuyrukta bekler ve sistemin di\u011fer b\u00f6l\u00fcmleri \u00e7al\u0131\u015fmaya devam eder. Bu, kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan arka planda sorunlar\u0131n \u00e7\u00f6z\u00fclmesine olanak tan\u0131r. Olay odakl\u0131 mimari, b\u00f6ylece sisteminizin daha \u00e7evik ve de\u011fi\u015fen i\u015f gereksinimlerine daha h\u0131zl\u0131 adapte olabilen bir yap\u0131ya b\u00fcr\u00fcnmesini sa\u011flar.<\/p>\n<p>Gev\u015fek ba\u011fl\u0131l\u0131k, \u00f6l\u00e7eklenebilirlik, esneklik ve dayan\u0131kl\u0131l\u0131k gibi \u00f6zellikler, \u00f6zellikle mikroservis mimarileri, IoT uygulamalar\u0131, ger\u00e7ek zamanl\u0131 veri i\u015fleme ve b\u00fcy\u00fck \u00f6l\u00e7ekli kurumsal uygulamalar i\u00e7in EDA&#8217;y\u0131 vazge\u00e7ilmez k\u0131lar. Sistemlerinizi daha mod\u00fcler, y\u00f6netilebilir ve gelecekteki de\u011fi\u015fikliklere daha a\u00e7\u0131k hale getirmenizi sa\u011flar. Bu nedenle, modern yaz\u0131l\u0131m geli\u015ftirme pratiklerinde EDA&#8217;y\u0131 anlamak ve uygulamak, rekabet\u00e7i kalmak isteyen her geli\u015ftirici i\u00e7in kritik bir beceridir. Bir ba\u015fka deyi\u015fle, EDA, kompleks sistemlerin karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 y\u00f6netmek i\u00e7in g\u00fc\u00e7l\u00fc bir ara\u00e7 seti sunar. Sisteminizdeki her bir par\u00e7an\u0131n, di\u011fer par\u00e7alar\u0131n durumu hakk\u0131nda \u00e7ok az bilgiye sahip olarak veya hi\u00e7 sahip olmadan kendi g\u00f6revini yerine getirebilmesini sa\u011flar. Bu, geli\u015ftirme s\u00fcre\u00e7lerini h\u0131zland\u0131r\u0131r, hatalar\u0131n yay\u0131lmas\u0131n\u0131 engeller ve genel sistemin bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r. Ayr\u0131ca, yeni \u00f6zellikler eklemek veya mevcut i\u015flevleri de\u011fi\u015ftirmek \u00e7ok daha kolay hale gelir, \u00e7\u00fcnk\u00fc tek bir servis \u00fczerinde yap\u0131lan bir de\u011fi\u015fiklik di\u011fer servisleri do\u011frudan etkilemez, b\u00f6ylece ba\u011f\u0131ms\u0131z da\u011f\u0131t\u0131m (independent deployment) imkan\u0131 sunar.<\/p>\n<p>\u00d6zetle, Olay Odakl\u0131 Mimari, modern yaz\u0131l\u0131m sistemlerinin kar\u015f\u0131la\u015ft\u0131\u011f\u0131 zorluklara kar\u015f\u0131 g\u00fc\u00e7l\u00fc ve esnek bir \u00e7\u00f6z\u00fcm sunar. Bile\u015fenler aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 azaltarak, sistemlerinizi daha dayan\u0131kl\u0131, \u00f6l\u00e7eklenebilir ve y\u00f6netilebilir hale getirir. Bu yakla\u015f\u0131m, g\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen i\u015f d\u00fcnyas\u0131n\u0131n taleplerini kar\u015f\u0131lamak ve s\u00fcrekli b\u00fcy\u00fcyen dijital ihtiya\u00e7lara yan\u0131t vermek i\u00e7in kritik bir rol oynamaktad\u0131r. Ayr\u0131ca, \u015firketlerin h\u0131zl\u0131 bir \u015fekilde inovasyon yapmas\u0131na ve piyasaya yeni \u00fcr\u00fcn ve hizmetler sunmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<h2>RabbitMQ Nedir ve Olay Odakl\u0131 Mimaride Nas\u0131l Bir Rol Oynar?<\/h2>\n<p>Olay odakl\u0131 mimarinin temel ta\u015f\u0131y\u0131c\u0131lar\u0131ndan biri de mesaj kuyruklar\u0131d\u0131r. \u0130\u015fte bu noktada RabbitMQ sahneye \u00e7\u0131k\u0131yor. RabbitMQ, Advanced Message Queuing Protocol (AMQP) standard\u0131n\u0131 uygulayan a\u00e7\u0131k kaynakl\u0131, \u00e7ok y\u00f6nl\u00fc bir mesaj broker\u0131d\u0131r. Basit\u00e7e ifade etmek gerekirse, RabbitMQ, uygulamalar aras\u0131nda mesaj al\u0131\u015fveri\u015fini sa\u011flayan bir posta ofisi gibidir. Bir uygulama (\u00fcretici\/publisher) mesajlar\u0131 RabbitMQ&#8217;ya g\u00f6nderir, di\u011fer uygulamalar (t\u00fcketici\/consumer) ise bu mesajlar\u0131 RabbitMQ&#8217;dan al\u0131r. Bu sayede, uygulamalar birbirleriyle do\u011frudan konu\u015fmak yerine RabbitMQ arac\u0131l\u0131\u011f\u0131yla asenkron olarak ileti\u015fim kurarlar. Bu dolayl\u0131 ileti\u015fim, servislerin gev\u015fek ba\u011fl\u0131 olmas\u0131n\u0131 ve birbirlerinin varl\u0131\u011f\u0131ndan haberdar olmadan \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. RabbitMQ&#8217;nun bu merkezi rol\u00fc, olay odakl\u0131 mimarilerde kritik \u00f6neme sahiptir \u00e7\u00fcnk\u00fc olaylar\u0131n g\u00fcvenilir ve verimli bir \u015fekilde da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>RabbitMQ, mesajlar\u0131n g\u00fcvenilir bir \u015fekilde iletilmesini sa\u011flar. Mesajlar kaybolmaz; bir t\u00fcketici mesaj\u0131 alana kadar kuyrukta bekler. Bu, \u00f6zellikle sistemin kritik i\u015f ak\u0131\u015flar\u0131nda veri kayb\u0131n\u0131 \u00f6nlemek a\u00e7\u0131s\u0131ndan \u00e7ok \u00f6nemlidir. Ayr\u0131ca, mesajlar\u0131n birden fazla t\u00fcketiciye da\u011f\u0131t\u0131labilmesini veya belirli kriterlere g\u00f6re y\u00f6nlendirilebilmesini sa\u011flayan farkl\u0131 exchange (de\u011fi\u015ftirici) t\u00fcrleri sunar. Direct, Fanout, Topic ve Headers gibi exchange&#8217;ler, mesaj y\u00f6nlendirme mant\u0131\u011f\u0131n\u0131 esnek bir \u015fekilde yap\u0131land\u0131rman\u0131za olanak tan\u0131r. \u00d6rne\u011fin, bir Fanout exchange&#8217;i, ald\u0131\u011f\u0131 her mesaj\u0131 ba\u011fl\u0131 oldu\u011fu t\u00fcm kuyruklara kopyalarken, bir Topic exchange&#8217;i, mesajlar\u0131 y\u00f6nlendirme anahtarlar\u0131na (routing key) g\u00f6re belirli kuyruklara y\u00f6nlendirir ve wildcard karakterler (*, #) ile daha karma\u015f\u0131k y\u00f6nlendirme desenlerini destekler. Bu esneklik, farkl\u0131 olay t\u00fcrlerinin farkl\u0131 i\u015f ak\u0131\u015flar\u0131 taraf\u0131ndan i\u015flenmesini kolayla\u015ft\u0131r\u0131r ve sistem tasar\u0131m\u0131n\u0131za b\u00fcy\u00fck bir serbestlik kazand\u0131r\u0131r.<\/p>\n<p>Olay odakl\u0131 mimaride RabbitMQ&#8217;nun rol\u00fc olduk\u00e7a geni\u015ftir ve temel faydalar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li><strong>Asenkron \u0130leti\u015fim:<\/strong> Uygulamalar\u0131n birbirlerinin yan\u0131t\u0131n\u0131 beklemeden olaylar\u0131 yay\u0131nlay\u0131p t\u00fcketmesini sa\u011flar. Bu, sistemin genel yan\u0131t s\u00fcresini d\u00fc\u015f\u00fcr\u00fcr, arka plan i\u015flemlerinin verimli bir \u015fekilde y\u00fcr\u00fct\u00fclmesine olanak tan\u0131r ve b\u00f6ylece performans\u0131 art\u0131r\u0131r.<\/li>\n<li><strong>Gev\u015fek Ba\u011fl\u0131l\u0131k:<\/strong> \u00dcreticilerin t\u00fcketicileri do\u011frudan bilmesine gerek kalmadan mesaj g\u00f6ndermesine olanak tan\u0131r. Bu, sistem bile\u015fenlerinin daha ba\u011f\u0131ms\u0131z olmas\u0131n\u0131 ve daha kolay geli\u015ftirilip da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar, ayr\u0131ca monolitik ba\u011f\u0131ml\u0131l\u0131klar\u0131n \u00f6n\u00fcne ge\u00e7er.<\/li>\n<li><strong>Y\u00fck Dengeleme:<\/strong> Birden fazla t\u00fcketicinin ayn\u0131 kuyru\u011fu dinlemesini sa\u011flayarak i\u015f y\u00fck\u00fcn\u00fcn t\u00fcketiciler aras\u0131nda e\u015fit ve etkili bir \u015fekilde da\u011f\u0131t\u0131lmas\u0131na yard\u0131mc\u0131 olur. Bu, sistemin yatay \u00f6l\u00e7eklenebilirli\u011fini art\u0131r\u0131r ve performansta darbo\u011faz olu\u015fmas\u0131n\u0131 engeller.<\/li>\n<li><strong>Mesaj Dayan\u0131kl\u0131l\u0131\u011f\u0131:<\/strong> Mesajlar\u0131 kal\u0131c\u0131 (durable) hale getirerek RabbitMQ sunucusu \u00e7\u00f6kse bile mesajlar\u0131n kaybolmamas\u0131n\u0131 sa\u011flar. Bu, sistemin g\u00fcvenilirli\u011fini art\u0131r\u0131r ve veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korur.<\/li>\n<li><strong>Hata Tolerans\u0131:<\/strong> Bir t\u00fcketici servisi ar\u0131zaland\u0131\u011f\u0131nda veya yava\u015flad\u0131\u011f\u0131nda, mesajlar kuyrukta bekler ve servis d\u00fczeldi\u011finde i\u015flenmeye devam eder. Bu, sistemin hata tolerans\u0131n\u0131 art\u0131r\u0131r ve ge\u00e7ici aksakl\u0131klar\u0131n genel sistemi etkilemesini \u00f6nler.<\/li>\n<li><strong>\u00d6l\u00e7eklenebilirlik:<\/strong> Y\u00fcksek trafik alt\u0131nda bile mesajlar\u0131n verimli bir \u015fekilde i\u015flenmesini sa\u011flar. \u0130htiya\u00e7 duyuldu\u011funda kolayca yeni t\u00fcketici \u00f6rnekleri ekleyebilirsiniz. Bu dinamik \u00f6l\u00e7eklendirme yetene\u011fi, de\u011fi\u015fen talep yo\u011funluklar\u0131na h\u0131zl\u0131ca adapte olmay\u0131 sa\u011flar.<\/li>\n<\/ul>\n<p>\u00d6rnek bir senaryoda, bir kullan\u0131c\u0131n\u0131n web sitesi \u00fczerinden bir sipari\u015f verdi\u011fini d\u00fc\u015f\u00fcnelim. Web aray\u00fcz\u00fc, sipari\u015f bilgilerini bir &#8220;Sipari\u015f Y\u00f6neticisi&#8221; mikroservisine g\u00f6nderir. Sipari\u015f Y\u00f6neticisi, sipari\u015fi veritaban\u0131na kaydettikten sonra, bir &#8220;Sipari\u015f Olu\u015fturuldu&#8221; olay\u0131n\u0131 RabbitMQ&#8217;daki bir exchange&#8217;e yay\u0131nlar. Bu exchange&#8217;e ba\u011fl\u0131 olan &#8220;Envanter Y\u00f6neticisi&#8221; servisi stoklar\u0131 g\u00fcnceller, &#8220;\u00d6deme Y\u00f6neticisi&#8221; servisi \u00f6deme i\u015flemini ba\u015flat\u0131r ve &#8220;Bildirim Servisi&#8221; m\u00fc\u015fteriye bir e-posta g\u00f6nderir. T\u00fcm bu i\u015flemler birbirinden ba\u011f\u0131ms\u0131z ve asenkron olarak ger\u00e7ekle\u015fir. E\u011fer Envanter Y\u00f6neticisi anl\u0131k olarak yo\u011funsa, mesaj kuyrukta bekler ve di\u011fer servisler kendi i\u015flemlerini sorunsuz bir \u015fekilde tamamlar. Bu mimari, sistemin genel olarak daha dayan\u0131kl\u0131, h\u0131zl\u0131 ve esnek olmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>RabbitMQ, mesajlar\u0131n do\u011fru ve g\u00fcvenilir bir \u015fekilde hedeflerine ula\u015fmas\u0131n\u0131 sa\u011flarken, olay odakl\u0131 mimarinin sundu\u011fu t\u00fcm avantajlardan faydalanman\u0131z\u0131 garantileyen g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r. Bu sayede, karma\u015f\u0131k ve da\u011f\u0131t\u0131k sistemlerinizi daha etkili bir \u015fekilde y\u00f6netebilir, servisleriniz aras\u0131ndaki ileti\u015fimi g\u00fc\u00e7lendirebilirsiniz.<\/p>\n<div class=\"interactive-tip\">\n        Uzman \u0130pucu: RabbitMQ&#8217;da Exchange&#8217;ler, mesajlar\u0131n\u0131z\u0131 nas\u0131l y\u00f6nlendirece\u011finizi belirleyen anahtar bile\u015fenlerdir. Projenizin ihtiya\u00e7lar\u0131na g\u00f6re do\u011fru Exchange tipini (Direct, Fanout, Topic, Headers) se\u00e7mek, mesajla\u015fma performans\u0131n\u0131z\u0131 ve esnekli\u011finizi do\u011frudan etkiler. Ba\u015flang\u0131\u00e7ta Fanout basit bir se\u00e7im gibi g\u00f6r\u00fcnse de, daha karma\u015f\u0131k y\u00f6nlendirme ihtiya\u00e7lar\u0131 i\u00e7in Topic veya Direct exchange&#8217;leri kullanmak daha verimlidir. \u00d6zellikle mikroservisler aras\u0131 farkl\u0131 olay tipleri ve filtreleme gerektiren durumlarda Topic exchange vazge\u00e7ilmezdir.\n    <\/div>\n<h2>Java ile Olay Yay\u0131nc\u0131 (Publisher) Nas\u0131l Geli\u015ftirilir?<\/h2>\n<p>Java ekosistemi, RabbitMQ ile entegrasyon i\u00e7in zengin k\u00fct\u00fcphaneler sunar. Bu b\u00f6l\u00fcmde, basit bir Java uygulamas\u0131n\u0131n nas\u0131l olay yay\u0131nc\u0131 (publisher) olarak g\u00f6rev yapabilece\u011fini ad\u0131m ad\u0131m inceleyece\u011fiz. Olay yay\u0131nc\u0131, belirli bir olay\u0131n ger\u00e7ekle\u015fti\u011fini RabbitMQ&#8217;ya bildiren bile\u015fendir. Olay yay\u0131nc\u0131lar\u0131n\u0131n temel sorumlulu\u011fu, olaylar\u0131 olu\u015fturmak ve bunlar\u0131 do\u011fru exchange&#8217;e, uygun routing key ile g\u00f6ndermektir. \u00d6ncelikle, projemize RabbitMQ Java istemci k\u00fct\u00fcphanesini eklememiz gerekecek. Maven kullan\u0131yorsan\u0131z, <code>pom.xml<\/code> dosyan\u0131za a\u015fa\u011f\u0131daki ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 eklemelisiniz. Bu ba\u011f\u0131ml\u0131l\u0131k, RabbitMQ ile ileti\u015fim kurmak i\u00e7in gerekli t\u00fcm s\u0131n\u0131flar\u0131 ve metodlar\u0131 i\u00e7erir.<\/p>\n<pre><code class=\"language-xml\">\n<dependency>\n    <groupId>com.rabbitmq<\/groupId>\n    <artifactId>amqp-client<\/artifactId>\n    <version>5.20.0<\/version> <!-- En g\u00fcncel kararl\u0131 s\u00fcr\u00fcm\u00fc kullanman\u0131z \u00f6nerilir -->\n<\/dependency>\n    <\/pre>\n<p><\/code><\/p>\n<p>Ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 ekledikten sonra, RabbitMQ sunucusuna ba\u011flanmak ve bir mesaj yay\u0131nlamak i\u00e7in bir Java s\u0131n\u0131f\u0131 olu\u015fturabiliriz. A\u015fa\u011f\u0131daki \u00f6rnek, \"order_exchange\" ad\u0131nda bir topic exchange'e \"order.created\" routing key'i ile bir mesaj g\u00f6nderen basit bir yay\u0131nc\u0131y\u0131 g\u00f6stermektedir. Bu mesaj, JSON format\u0131nda bir sipari\u015f objesini temsil etmektedir. Uygulama, RabbitMQ ile ba\u011flant\u0131 kurar, bir kanal olu\u015fturur ve mesaj\u0131 bu kanal \u00fczerinden yay\u0131nlar. Yay\u0131nlama i\u015flemi tamamland\u0131ktan sonra, mesaj\u0131n ba\u015far\u0131yla g\u00f6nderildi\u011fini belirten bir mesaj konsola yazd\u0131r\u0131l\u0131r. Ba\u011flant\u0131 ve kanal kaynaklar\u0131n\u0131n <code>try-with-resources<\/code> blo\u011fu ile otomatik olarak kapat\u0131lmas\u0131, kaynak y\u00f6netimi a\u00e7\u0131s\u0131ndan \u00f6nemlidir.<\/p>\n<pre><code class=\"language-java\">\nimport com.rabbitmq.client.Channel;\nimport com.rabbitmq.client.Connection;\nimport com.rabbitmq.client.ConnectionFactory;\nimport com.rabbitmq.client.AMQP; \/\/ Mesaj \u00f6zelliklerini (durability) belirtmek i\u00e7in\n\nimport java.nio.charset.StandardCharsets;\n\npublic class OrderEventPublisher {\n\n    private final static String EXCHANGE_NAME = \"order_exchange\"; \/\/ Kullan\u0131lacak Exchange ad\u0131\n    private final static String ROUTING_KEY = \"order.created\";    \/\/ Mesaj\u0131n y\u00f6nlendirilece\u011fi anahtar\n\n    public static void main(String[] argv) throws Exception {\n        ConnectionFactory factory = new ConnectionFactory();\n        factory.setHost(\"localhost\"); \/\/ RabbitMQ sunucunuzun adresi, Docker kullan\u0131yorsan\u0131z 'rabbitmq' olabilir\n        factory.setPort(5672);        \/\/ Varsay\u0131lan RabbitMQ portu\n        factory.setUsername(\"guest\"); \/\/ Varsay\u0131lan kullan\u0131c\u0131 ad\u0131\n        factory.setPassword(\"guest\"); \/\/ Varsay\u0131lan \u015fifre\n\n        \/\/ try-with-resources kullanarak ba\u011flant\u0131 ve kanal\u0131 otomatik kapatma\n        try (Connection connection = factory.newConnection();\n             Channel channel = connection.createChannel()) {\n\n            \/\/ Exchange'i tan\u0131mlama: Topic exchange kullan\u0131yoruz. Durable: true ile kal\u0131c\u0131 hale getiriyoruz.\n            channel.exchangeDeclare(EXCHANGE_NAME, \"topic\", true);\n\n            \/\/ G\u00f6nderilecek mesaj i\u00e7eri\u011fi (JSON format\u0131nda bir sipari\u015f bilgisi)\n            String message = \"{\\\"orderId\\\": \\\"ABC-123\\\", \\\"customer\\\": \\\"Ahmet Y\u0131lmaz\\\", \\\"amount\\\": 150.75, \\\"items\\\": [{\\\"productId\\\": \\\"P001\\\", \\\"quantity\\\": 1}]}\";\n            \n            \/\/ Mesaj \u00f6zelliklerini (properties) belirleme: deliveryMode(2) ile kal\u0131c\u0131 (persistent) yap\u0131yoruz.\n            AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()\n                                            .contentType(\"application\/json\")\n                                            .deliveryMode(2) \/\/ 2 = persistent (kal\u0131c\u0131)\n                                            .build();\n\n            \/\/ Mesaj\u0131 yay\u0131nlama\n            channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, props, message.getBytes(StandardCharsets.UTF_8));\n            System.out.println(\" [x] '\" + ROUTING_KEY + \"' routing key'i ile kal\u0131c\u0131 mesaj g\u00f6nderildi: '\" + message + \"'\");\n        }\n    }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kod blo\u011funda g\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, <code>ConnectionFactory<\/code> ile RabbitMQ sunucusuna bir ba\u011flant\u0131 olu\u015fturulur. Bu ba\u011flant\u0131, mesajla\u015fma i\u00e7in fiziksel bir kanald\u0131r. Ard\u0131ndan, bu ba\u011flant\u0131 \u00fczerinden bir <code>Channel<\/code> (kanal) a\u00e7\u0131l\u0131r. T\u00fcm mesajla\u015fma i\u015flemleri, yani mesaj g\u00f6nderme ve alma, bu kanal \u00fczerinden ger\u00e7ekle\u015fir. <code>exchangeDeclare<\/code> metodu ile <code>order_exchange<\/code> ad\u0131nda bir topic exchange tan\u0131ml\u0131yoruz. Topic exchange'ler, routing key'lere g\u00f6re esnek mesaj y\u00f6nlendirmesi sa\u011flad\u0131\u011f\u0131 i\u00e7in olay odakl\u0131 mimarilerde s\u0131kl\u0131kla tercih edilir. <code>durable: true<\/code> parametresi, RabbitMQ sunucusu yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda bile exchange'in varl\u0131\u011f\u0131n\u0131 korumas\u0131n\u0131 sa\u011flar, bu da dayan\u0131kl\u0131l\u0131k a\u00e7\u0131s\u0131ndan \u00f6nemlidir. Mesaj\u0131n kal\u0131c\u0131l\u0131\u011f\u0131 i\u00e7in <code>AMQP.BasicProperties<\/code> kullanarak <code>deliveryMode(2)<\/code> ayar\u0131 yap\u0131l\u0131r, bu da RabbitMQ'nun mesaj\u0131 diske yazmas\u0131n\u0131 ve sunucu \u00e7\u00f6kse bile mesaj\u0131n kaybolmamas\u0131n\u0131 garanti eder.<\/p>\n<p><code>basicPublish<\/code> metodu ile mesaj\u0131m\u0131z\u0131 exchange'e g\u00f6nderiyoruz. Parametreler s\u0131ras\u0131yla \u015funlard\u0131r:<\/p>\n<ol>\n<li><strong><code>EXCHANGE_NAME<\/code><\/strong>: Mesaj\u0131n g\u00f6nderilece\u011fi exchange'in ad\u0131.<\/li>\n<li><strong><code>ROUTING_KEY<\/code><\/strong>: Mesaj\u0131n y\u00f6nlendirme anahtar\u0131. Bu anahtar, t\u00fcketicilerin hangi mesajlar\u0131 alaca\u011f\u0131n\u0131 belirlemede kullan\u0131l\u0131r. <code>order.created<\/code> \u00f6rne\u011fi, sipari\u015fle ilgili ve olu\u015fturma olay\u0131n\u0131 temsil eder.<\/li>\n<li><strong><code>props<\/code><\/strong>: Mesaj \u00f6zellikleri (kal\u0131c\u0131l\u0131k, i\u00e7erik tipi, ba\u015fl\u0131klar vb.). Burada mesaj\u0131 kal\u0131c\u0131 (persistent) olarak i\u015faretliyor ve i\u00e7erik tipini belirtiyoruz.<\/li>\n<li><strong><code>body<\/code><\/strong>: Mesaj\u0131n i\u00e7eri\u011fi (byte dizisi olarak). Burada JSON format\u0131nda bir sipari\u015f bilgisi g\u00f6nderiyoruz.<\/li>\n<\/ol>\n<p>    Bu basit yay\u0131nc\u0131, RabbitMQ'ya bir olay g\u00f6ndererek, bu olay\u0131 dinleyen t\u00fcm t\u00fcketicilerin tetiklenmesini sa\u011flar. Ger\u00e7ek d\u00fcnya senaryolar\u0131nda, bu yay\u0131nc\u0131 bir mikroservisin i\u015f mant\u0131\u011f\u0131n\u0131n bir par\u00e7as\u0131 olarak \u00e7al\u0131\u015f\u0131r ve bir veritaban\u0131 i\u015flemi tamamland\u0131ktan sonra veya bir API \u00e7a\u011fr\u0131s\u0131 al\u0131nd\u0131\u011f\u0131nda ilgili olay\u0131 yay\u0131nlar. \u00d6rne\u011fin, bir sipari\u015f hizmeti, veritaban\u0131na yeni bir sipari\u015f kayd\u0131 ekledikten hemen sonra bu <code>OrderEventPublisher<\/code> s\u0131n\u0131f\u0131n\u0131 kullanarak bir \"Sipari\u015f Olu\u015fturuldu\" olay\u0131 yay\u0131nlayabilir. Bu, sisteminizin farkl\u0131 b\u00f6l\u00fcmlerinin senkronizasyonunu ve i\u015f ak\u0131\u015flar\u0131n\u0131n otomatikle\u015fmesini sa\u011flar. Bu yap\u0131, \u00f6zellikle karma\u015f\u0131k i\u015f s\u00fcre\u00e7lerinin oldu\u011fu ve birden fazla servisin ayn\u0131 olayla ilgilendi\u011fi durumlarda b\u00fcy\u00fck fayda sa\u011flar. Bu, mikroservislerin birbirlerinden izole \u00e7al\u0131\u015fmas\u0131na olanak tan\u0131r ve genel sistemin esnekli\u011fini ve bak\u0131m kolayl\u0131\u011f\u0131n\u0131 art\u0131r\u0131r. Olaylar\u0131n yay\u0131nlanmas\u0131, sistemin farkl\u0131 mod\u00fcllerinin ba\u011f\u0131ms\u0131z olarak evrimle\u015fmesine imkan tan\u0131rken, ayn\u0131 zamanda bilgi ak\u0131\u015f\u0131n\u0131 da g\u00fcvenilir bir \u015fekilde s\u00fcrd\u00fcr\u00fcr.<\/p>\n<h2>Java ile Olay T\u00fcketici (Consumer) Nas\u0131l Geli\u015ftirilir?<\/h2>\n<p>Olay odakl\u0131 mimarinin di\u011fer y\u00fcz\u00fc ise olay t\u00fcketicileridir (consumers). T\u00fcketiciler, RabbitMQ'daki kuyruklardan mesajlar\u0131 dinleyip i\u015fleyen uygulamalard\u0131r. Bu bile\u015fenler, yay\u0131nlanan olaylara tepki verir ve kendi i\u015f mant\u0131klar\u0131n\u0131 bu olaylara g\u00f6re y\u00fcr\u00fct\u00fcrler. \u015eimdi, Java ile nas\u0131l bir t\u00fcketici geli\u015ftirebilece\u011fimize bakal\u0131m. T\u0131pk\u0131 yay\u0131nc\u0131da oldu\u011fu gibi, \u00f6ncelikle RabbitMQ Java istemci k\u00fct\u00fcphanesini projemize eklemi\u015f olmam\u0131z gerekiyor. T\u00fcketici uygulamas\u0131, belirli bir exchange'e ba\u011fl\u0131 bir kuyru\u011fu dinleyecek ve bu kuyru\u011fa gelen mesajlar\u0131 i\u015fleyecektir. A\u015fa\u011f\u0131daki \u00f6rnek, <code>order_exchange<\/code>'den \"order.created\" routing key'ine sahip mesajlar\u0131 dinleyen bir t\u00fcketiciyi g\u00f6stermektedir. Bu t\u00fcketici, mesajlar\u0131 al\u0131r, i\u015fler ve ard\u0131ndan RabbitMQ'ya ba\u015far\u0131l\u0131 bir \u015fekilde i\u015flendi\u011fini bildirir. \u0130\u015fleme s\u0131ras\u0131nda bir hata olu\u015fursa, mesaj\u0131n durumunu y\u00f6netme mekanizmalar\u0131n\u0131 da i\u00e7ermektedir.<\/p>\n<pre><code class=\"language-java\">\nimport com.rabbitmq.client.Channel;\nimport com.rabbitmq.client.Connection;\nimport com.rabbitmq.client.ConnectionFactory;\nimport com.rabbitmq.client.DeliverCallback;\nimport com.rabbitmq.client.BuiltinExchangeType; \/\/ Exchange tipi i\u00e7in\n\nimport java.nio.charset.StandardCharsets;\n\npublic class OrderEventConsumer {\n\n    private final static String EXCHANGE_NAME = \"order_exchange\";\n    private final static String QUEUE_NAME = \"order_created_queue\"; \/\/ Kuyruk ad\u0131\n    private final static String ROUTING_KEY = \"order.created\";       \/\/ Ba\u011flan\u0131lacak routing key\n\n    public static void main(String[] argv) throws Exception {\n        ConnectionFactory factory = new ConnectionFactory();\n        factory.setHost(\"localhost\");\n        factory.setPort(5672);\n        factory.setUsername(\"guest\");\n        factory.setPassword(\"guest\");\n\n        \/\/ Ba\u011flant\u0131 ve kanal olu\u015fturma\n        Connection connection = factory.newConnection();\n        Channel channel = connection.createChannel();\n\n        \/\/ Exchange'i tan\u0131mlama (Publisher ile ayn\u0131 olmal\u0131). Durable: true.\n        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC, true);\n\n        \/\/ Kuyru\u011fu tan\u0131mlama (Durable: true, non-exclusive, non-autoDelete)\n        \/\/ E\u011fer kuyruk zaten varsa, var olan \u00f6zellikleri ile kullan\u0131l\u0131r.\n        channel.queueDeclare(QUEUE_NAME, true, false, false, null);\n\n        \/\/ Kuyru\u011fu exchange'e ba\u011flama. Bu sayede exchange'e gelen ilgili mesajlar bu kuyru\u011fa y\u00f6nlendirilir.\n        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);\n        System.out.println(\" [*] '\" + QUEUE_NAME + \"' kuyru\u011fundan mesajlar bekleniyor. \u00c7\u0131kmak i\u00e7in CTRL+C yap\u0131n.\");\n\n        \/\/ Mesaj teslim edildi\u011finde \u00e7al\u0131\u015facak callback fonksiyonu tan\u0131mlama\n        DeliverCallback deliverCallback = (consumerTag, delivery) -> {\n            String message = new String(delivery.getBody(), StandardCharsets.UTF_8);\n            System.out.println(\" [x] Mesaj al\u0131nd\u0131 ('\" + ROUTING_KEY + \"'): '\" + message + \"'\");\n            \n            \/\/ Ger\u00e7ek d\u00fcnya senaryosunda, burada i\u015f mant\u0131\u011f\u0131 uygulan\u0131r.\n            \/\/ \u00d6rne\u011fin, stok g\u00fcncelleme, \u00f6deme i\u015fleme, bildirim g\u00f6nderme.\n            try {\n                \/\/ \u0130\u015flem s\u00fcresini taklit edelim\n                Thread.sleep(2000); \n                System.out.println(\" [x] Mesaj ba\u015far\u0131yla i\u015flendi: \" + message);\n                \/\/ Mesaj ba\u015far\u0131yla i\u015flendi\u011finde RabbitMQ'ya onay g\u00f6nderiyoruz\n                channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); \n            } catch (InterruptedException e) {\n                \/\/ Thread kesintiye u\u011frarsa\n                Thread.currentThread().interrupt();\n                System.err.println(\" [x] Mesaj i\u015flenirken kesinti olu\u015ftu: \" + message);\n                \/\/ Mesaj\u0131 tekrar kuyru\u011fa g\u00f6ndermeyi deneme (birden fazla yeniden denemeyi engellemek i\u00e7in dikkatli kullan\u0131lmal\u0131)\n                channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, true); \n            } catch (Exception e) {\n                \/\/ Di\u011fer t\u00fcm hatalar i\u00e7in\n                System.err.println(\" [x] Mesaj i\u015flenirken genel hata olu\u015ftu: \" + message + \" - Hata: \" + e.getMessage());\n                \/\/ Mesaj\u0131 reddet ve tekrar kuyru\u011fa g\u00f6nderme (Dead Letter Queue'ya y\u00f6nlendirme i\u00e7in ideal)\n                channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false); \n            }\n        };\n\n        \/\/ Mesajlar\u0131 dinlemeye ba\u015fla. autoAck: false, manuel onaylama yapaca\u011f\u0131m\u0131z\u0131 belirtir.\n        channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {}); \n    }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu t\u00fcketici kodu, \u00f6nce bir ba\u011flant\u0131 ve kanal olu\u015fturur. Daha sonra, yay\u0131nc\u0131n\u0131n kulland\u0131\u011f\u0131 <code>order_exchange<\/code>'i tekrar tan\u0131mlar (bu, exchange'in varl\u0131\u011f\u0131n\u0131 garanti alt\u0131na al\u0131r ve RabbitMQ'ya exchange tipi ve kal\u0131c\u0131l\u0131k bilgilerini bildirir). Ard\u0131ndan, <code>order_created_queue<\/code> ad\u0131nda kal\u0131c\u0131 (durable) bir kuyruk tan\u0131mlar. Bu kuyruk, <code>order_exchange<\/code>'e <code>order.created<\/code> routing key'i ile ba\u011flan\u0131r. Bu ba\u011flama (binding) sayesinde, sadece bu routing key'e sahip mesajlar bu kuyru\u011fa y\u00f6nlendirilir. Bir exchange'e birden fazla kuyruk ba\u011flanabilir ve her kuyruk farkl\u0131 routing key desenleri kullanarak farkl\u0131 olay alt k\u00fcmelerini filtreleyebilir.<\/p>\n<p><code>DeliverCallback<\/code> aray\u00fcz\u00fc, RabbitMQ'dan bir mesaj al\u0131nd\u0131\u011f\u0131nda ne yap\u0131laca\u011f\u0131n\u0131 tan\u0131mlar. <code>handleDelivery<\/code> metodu, al\u0131nan mesaj\u0131n i\u00e7eri\u011fini (payload) al\u0131r ve ekrana yazd\u0131r\u0131r. Ger\u00e7ek bir uygulamada, bu b\u00f6l\u00fcmde karma\u015f\u0131k i\u015f mant\u0131\u011f\u0131 (veritaban\u0131 g\u00fcncellemeleri, di\u011fer API \u00e7a\u011fr\u0131lar\u0131, d\u0131\u015f sistem entegrasyonlar\u0131 vb.) y\u00fcr\u00fct\u00fcl\u00fcr. \u00d6rne\u011fin, bir \"Envanter Servisi\" bu t\u00fcketiciyi kullanarak <code>order.created<\/code> olaylar\u0131n\u0131 dinleyebilir ve sipari\u015f edilen \u00fcr\u00fcnlerin stoklar\u0131n\u0131 g\u00fcncelleyebilir. Ayn\u0131 \u015fekilde, bir \"Bildirim Servisi\" de bu olay\u0131 dinleyerek m\u00fc\u015fteriye sipari\u015f onay\u0131 e-postas\u0131 g\u00f6nderebilir. Bu sayede, sisteminizdeki farkl\u0131 mod\u00fcller, birbirlerinden ba\u011f\u0131ms\u0131z bir \u015fekilde ayn\u0131 olaylara tepki verebilir ve sistem genelinde paralel i\u015fleme yetene\u011fi kazan\u0131l\u0131r.<\/p>\n<p>Kodda dikkat edilmesi gereken \u00f6nemli bir nokta, <code>channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});<\/code> sat\u0131r\u0131ndaki <code>autoAck: false<\/code> parametresidir. Bu, mesaj\u0131n ba\u015far\u0131yla i\u015flendi\u011fini RabbitMQ'ya manuel olarak bildirmemiz gerekti\u011fi anlam\u0131na gelir. <code>channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);<\/code> \u00e7a\u011fr\u0131s\u0131, mesaj\u0131n ba\u015far\u0131yla i\u015flendi\u011fini ve kuyruktan silinebilece\u011fini RabbitMQ'ya bildirir. E\u011fer bir hata olu\u015fursa ve mesaj i\u015flenemezse (\u00f6rne\u011fin bir veritaban\u0131 hatas\u0131 veya i\u015f mant\u0131\u011f\u0131 hatas\u0131 nedeniyle), <code>basicNack<\/code> kullanarak mesaj\u0131n reddedildi\u011fini bildirebiliriz. <code>basicNack<\/code> metodunun son parametresi (<code>requeue: true<\/code> veya <code>false<\/code>), mesaj\u0131n tekrar kuyru\u011fa al\u0131n\u0131p al\u0131nmayaca\u011f\u0131n\u0131 belirler. E\u011fer <code>true<\/code> ise mesaj ba\u015fka bir t\u00fcketici taraf\u0131ndan tekrar i\u015flenmek \u00fczere kuyru\u011fa d\u00f6ner (ge\u00e7ici hatalar i\u00e7in uygundur). E\u011fer <code>false<\/code> ise mesaj kuyruktan kald\u0131r\u0131l\u0131r ve genellikle bir \"dead-letter queue\" (DLQ) mekanizmas\u0131 ile ba\u015fka bir kuyru\u011fa y\u00f6nlendirilir. Bu, hata durumlar\u0131nda mesaj kay\u0131plar\u0131n\u0131 \u00f6nlemek ve sistemin dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rmak i\u00e7in kritik bir mekanizmad\u0131r. Bu mekanizma sayesinde, bir mesaj i\u015flenirken meydana gelen ge\u00e7ici hatalar bile sistemin genelini etkilemez; mesaj yeniden i\u015flenmek \u00fczere kuyrukta bekler, kal\u0131c\u0131 hatalar ise \u00f6zel bir kuyrukta y\u00f6netilebilir.<\/p>\n<p>Bu yakla\u015f\u0131m, olay odakl\u0131 mimarinin temel prensiplerinden biri olan dayan\u0131kl\u0131l\u0131\u011f\u0131 ve g\u00fcvenilirli\u011fi sa\u011flar. T\u00fcketicilerin ba\u011f\u0131ms\u0131z olarak \u00f6l\u00e7eklenebilmesini ve i\u015f y\u00fck\u00fcn\u00fc etkili bir \u015fekilde da\u011f\u0131tabilmesini m\u00fcmk\u00fcn k\u0131lar. Her bir t\u00fcketici, kendi ya\u015fam d\u00f6ng\u00fcs\u00fcne sahip olabilir ve \u00f6l\u00e7eklenebilirlik ihtiya\u00e7lar\u0131na g\u00f6re dinamik olarak art\u0131r\u0131l\u0131p azalt\u0131labilir.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryosu: E-Ticaret Sipari\u015f S\u00fcreci Nas\u0131l Y\u00f6netilir?<\/h2>\n<p>Olay odakl\u0131 mimarinin ger\u00e7ek d\u00fcnyadaki g\u00fcc\u00fcn\u00fc anlamak i\u00e7in, pop\u00fcler bir e-ticaret uygulamas\u0131ndaki sipari\u015f s\u00fcrecini ele alal\u0131m. Geleneksel monolitik bir uygulamada, bir m\u00fc\u015fteri sipari\u015f verdi\u011finde, sipari\u015fin kaydedilmesi, envanterin g\u00fcncellenmesi, \u00f6demenin al\u0131nmas\u0131, e-posta g\u00f6nderilmesi ve lojistik s\u00fcrecinin ba\u015flat\u0131lmas\u0131 gibi ad\u0131mlar genellikle ayn\u0131 i\u015flem i\u00e7inde veya birbiri ard\u0131na senkronize olarak ger\u00e7ekle\u015ftirilir. Bu durum, bir ad\u0131mda ya\u015fanan bir sorunun t\u00fcm s\u00fcreci durdurmas\u0131na veya yava\u015flatmas\u0131na neden olabilir, bu da kullan\u0131c\u0131 deneyimini olumsuz etkiler ve sistemin genel dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 azalt\u0131r. Oysa olay odakl\u0131 mimari ile bu s\u00fcre\u00e7 tamamen de\u011fi\u015fir, \u00e7ok daha esnek ve hataya dayan\u0131kl\u0131 hale gelir.<\/p>\n<h3>Sipari\u015f Verme Ak\u0131\u015f\u0131 Olay Odakl\u0131 Mimari ile Nas\u0131l De\u011fi\u015fiyor?<\/h3>\n<p>M\u00fc\u015fteri bir sipari\u015f verdi\u011finde, \"Sipari\u015f Y\u00f6neticisi\" ad\u0131nda bir mikroservis bu iste\u011fi al\u0131r ve i\u015fleme ba\u015flar.<\/p>\n<ol>\n<li><strong>Sipari\u015f Olu\u015fturma (Publisher):<\/strong> Sipari\u015f Y\u00f6neticisi, m\u00fc\u015fteriden gelen sipari\u015f verilerini i\u015fler, gerekli \u00f6n do\u011frulamalar\u0131 yapar ve sipari\u015fi kendi veritaban\u0131na kaydeder. Sipari\u015f ba\u015far\u0131yla kaydedildikten hemen sonra, bir <code>Sipari\u015fOlu\u015fturuldu<\/code> olay\u0131n\u0131 RabbitMQ'daki <code>order_events<\/code> exchange'ine <code>order.created<\/code> routing key'i ile yay\u0131nlar. Bu i\u015flem asenkron oldu\u011fu i\u00e7in, Sipari\u015f Y\u00f6neticisi olay\u0131 yay\u0131nlad\u0131ktan hemen sonra m\u00fc\u015fteriye \"Sipari\u015finiz al\u0131nd\u0131\" yan\u0131t\u0131n\u0131 verebilir ve ba\u015fka i\u015fler yapmaya ba\u015flayabilir. Bu, ana uygulaman\u0131n h\u0131zl\u0131 yan\u0131t vermesini sa\u011flar.<\/li>\n<li><strong>Envanter G\u00fcncelleme (Consumer):<\/strong> Bir \"Envanter Y\u00f6neticisi\" mikroservisi, <code>order_events<\/code> exchange'ini <code>order.created<\/code> routing key'i ile dinler. <code>Sipari\u015fOlu\u015fturuldu<\/code> olay\u0131n\u0131 ald\u0131\u011f\u0131nda, ilgili \u00fcr\u00fcnlerin stoklar\u0131n\u0131 g\u00fcnceller. E\u011fer stokta yeterli \u00fcr\u00fcn yoksa (\u00f6rne\u011fin, ba\u015fka bir sipari\u015fle e\u015fzamanl\u0131 olarak stok t\u00fckenmi\u015fse), bu durum i\u00e7in farkl\u0131 bir olay (<code>StokYetersiz<\/code> veya <code>Sipari\u015fReddedildi<\/code>) yay\u0131nlayarak ilgili servislere bilgi verebilir.<\/li>\n<li><strong>\u00d6deme \u0130\u015fleme (Consumer):<\/strong> Bir \"\u00d6deme Y\u00f6neticisi\" mikroservisi de ayn\u0131 <code>order_events<\/code> exchange'ini <code>order.created<\/code> routing key'i ile dinler. Olay\u0131 ald\u0131\u011f\u0131nda, m\u00fc\u015fterinin kredi kart\u0131ndan \u00f6demeyi \u00e7ekme i\u015flemini ba\u015flat\u0131r. \u00d6deme ba\u015far\u0131l\u0131 olursa <code>\u00d6demeBa\u015far\u0131l\u0131<\/code> olay\u0131, ba\u015far\u0131s\u0131z olursa <code>\u00d6demeBa\u015far\u0131s\u0131z<\/code> olay\u0131 yay\u0131nlayabilir. Bu olaylar da di\u011fer servisler taraf\u0131ndan dinlenir ve gerekli aksiyonlar al\u0131n\u0131r. \u00d6rne\u011fin, <code>\u00d6demeBa\u015far\u0131s\u0131z<\/code> ise Sipari\u015f Y\u00f6neticisi sipari\u015fin durumunu g\u00fcncelleyebilir.<\/li>\n<li><strong>Bildirim G\u00f6nderme (Consumer):<\/strong> Bir \"Bildirim Servisi\", <code>order_events<\/code> exchange'ini <code>order.#<\/code> (order ile ba\u015flayan t\u00fcm routing key'ler) ve <code>payment.#<\/code> (payment ile ba\u015flayan t\u00fcm routing key'ler) gibi daha genel routing key'lerle dinleyebilir. <code>Sipari\u015fOlu\u015fturuldu<\/code> olay\u0131n\u0131 ald\u0131\u011f\u0131nda m\u00fc\u015fteriye sipari\u015f onay\u0131 e-postas\u0131 g\u00f6nderir. <code>\u00d6demeBa\u015far\u0131l\u0131<\/code> olay\u0131n\u0131 ald\u0131\u011f\u0131nda \u00f6deme onay\u0131, <code>\u00d6demeBa\u015far\u0131s\u0131z<\/code> olay\u0131n\u0131 ald\u0131\u011f\u0131nda ise \u00f6deme hatas\u0131 bildirimi g\u00f6nderebilir. Bu servis, ayn\u0131 zamanda SMS bildirimleri veya anl\u0131k bildirimler de g\u00f6nderebilir.<\/li>\n<li><strong>Lojistik ve Kargo Haz\u0131rl\u0131\u011f\u0131 (Consumer):<\/strong> \"Lojistik Servisi\" de <code>Sipari\u015fOlu\u015fturuldu<\/code> olay\u0131n\u0131 dinleyerek kargoya haz\u0131rl\u0131k s\u00fcrecini ba\u015flatabilir. Gerekli kargo fi\u015flerini olu\u015fturur, depodaki \u00fcr\u00fcnlerin toplanmas\u0131 i\u00e7in talimatlar verir ve bir <code>KargoHaz\u0131rland\u0131<\/code> olay\u0131 yay\u0131nlayabilir.<\/li>\n<\/ol>\n<p>Bu senaryoda, her servis kendi i\u015fini ba\u011f\u0131ms\u0131z olarak ve asenkron bir \u015fekilde yapar. Bir serviste ya\u015fanan gecikme veya hata, di\u011fer servislerin i\u015fleyi\u015fini do\u011frudan etkilemez. \u00d6rne\u011fin, \u00f6deme servisi ge\u00e7ici olarak kullan\u0131lamaz hale gelirse, <code>Sipari\u015fOlu\u015fturuldu<\/code> olay\u0131 ilgili kuyrukta bekler ve \u00f6deme servisi tekrar \u00e7al\u0131\u015f\u0131r duruma geldi\u011finde i\u015flenir. Bu, kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmaz ve sistemin genel dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r. Ayr\u0131ca, yeni bir \u00f6zellik (\u00f6rne\u011fin, sipari\u015fin sosyal medyada payla\u015f\u0131lmas\u0131 veya puan kazanma sistemi) eklemek istedi\u011finizde, sadece bu yeni \u00f6zelli\u011fi dinleyen bir mikroservis yazman\u0131z ve onu <code>order_events<\/code> exchange'ine ba\u011flaman\u0131z yeterli olur; mevcut kod taban\u0131nda neredeyse hi\u00e7bir de\u011fi\u015fiklik yapman\u0131za gerek kalmaz. Bu, sistemin mod\u00fclerli\u011fini, bak\u0131m kolayl\u0131\u011f\u0131n\u0131 ve geli\u015ftirme h\u0131z\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Olay odakl\u0131 mimari sayesinde, e-ticaret platformlar\u0131 h\u0131zla b\u00fcy\u00fcyebilir, yeni \u00f6zellikler ekleyebilir ve milyonlarca kullan\u0131c\u0131ya kesintisiz hizmet sunabilir.<\/p>\n<p>Olay odakl\u0131 mimari, e-ticaret gibi y\u00fcksek hacimli ve karma\u015f\u0131k i\u015f s\u00fcre\u00e7lerine sahip sistemler i\u00e7in m\u00fckemmel bir \u00e7\u00f6z\u00fcmd\u00fcr. Gev\u015fek ba\u011fl\u0131l\u0131k, \u00f6l\u00e7eklenebilirlik, esneklik ve hata tolerans\u0131 sa\u011flayarak, i\u015fletmelerin daha h\u0131zl\u0131 inovasyon yapmas\u0131na, m\u00fc\u015fteri memnuniyetini art\u0131rmas\u0131na ve rekabet\u00e7i avantaj elde etmesine olanak tan\u0131r. Bu sayede, sistemler daha \u00e7evik ve de\u011fi\u015fen pazar ko\u015fullar\u0131na daha h\u0131zl\u0131 adapte olabilirler. Ayr\u0131ca, farkl\u0131 servislerin farkl\u0131 teknolojilerle (\u00f6rne\u011fin, bir servis Python'da, di\u011feri Java'da yaz\u0131lm\u0131\u015f olabilir) geli\u015ftirilmesine izin vererek teknolojik \u00e7e\u015fitlili\u011fi de destekler.<\/p>\n<h2>\u0130leri D\u00fczey Kullan\u0131m: Mesaj Dayan\u0131kl\u0131l\u0131\u011f\u0131, Ack\/Nack ve Spring AMQP ile G\u00fcvenli \u0130leti\u015fim<\/h2>\n<p>Olay odakl\u0131 mimariyi production ortam\u0131nda kullan\u0131rken g\u00f6z \u00f6n\u00fcnde bulundurman\u0131z gereken bir\u00e7ok ileri d\u00fczey konu vard\u0131r. Bunlar, sisteminizin g\u00fcvenilirli\u011fini, performans\u0131n\u0131 ve y\u00f6netilebilirli\u011fini do\u011frudan etkiler. Bu b\u00f6l\u00fcmde, mesajlar\u0131n\u0131z\u0131n kaybolmamas\u0131n\u0131 ve hatalar\u0131n do\u011fru bir \u015fekilde ele al\u0131nmas\u0131n\u0131 sa\u011flayan kritik mekanizmalar\u0131 ve Spring ekosisteminde RabbitMQ entegrasyonunu kolayla\u015ft\u0131ran Spring AMQP'yi inceleyece\u011fiz.<\/p>\n<h3>Mesaj Dayan\u0131kl\u0131l\u0131\u011f\u0131 (Message Durability) ve Kal\u0131c\u0131l\u0131k Nas\u0131l Sa\u011flan\u0131r?<\/h3>\n<p>Bir mesaj broker'\u0131 kullanman\u0131n ana nedenlerinden biri, mesajlar\u0131n kaybolmamas\u0131n\u0131 sa\u011flamakt\u0131r, \u00f6zellikle de sistem \u00e7\u00f6kmeleri veya yeniden ba\u015flatmalar s\u00f6z konusu oldu\u011funda. RabbitMQ'da mesaj dayan\u0131kl\u0131l\u0131\u011f\u0131 \u00fc\u00e7 ana fakt\u00f6re ba\u011fl\u0131d\u0131r:<\/p>\n<ol>\n<li><strong>Exchange Dayan\u0131kl\u0131l\u0131\u011f\u0131:<\/strong> <code>channel.exchangeDeclare(EXCHANGE_NAME, \"topic\", true);<\/code> \u00e7a\u011fr\u0131s\u0131ndaki <code>true<\/code> parametresi exchange'i kal\u0131c\u0131 (durable) yapar. Bu, RabbitMQ sunucusu beklenmedik bir \u015fekilde kapat\u0131l\u0131p yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda exchange'in silinmeyece\u011fi, yap\u0131land\u0131rmas\u0131n\u0131n korunaca\u011f\u0131 anlam\u0131na gelir.<\/li>\n<li><strong>Kuyruk Dayan\u0131kl\u0131l\u0131\u011f\u0131:<\/strong> <code>channel.queueDeclare(QUEUE_NAME, true, false, false, null);<\/code> \u00e7a\u011fr\u0131s\u0131ndaki ilk <code>true<\/code> parametresi kuyru\u011fu kal\u0131c\u0131 yapar. Benzer \u015fekilde, sunucu yeniden ba\u015flat\u0131lsa bile kuyruk varl\u0131\u011f\u0131n\u0131 s\u00fcrd\u00fcr\u00fcr ve i\u00e7erisindeki kal\u0131c\u0131 mesajlar\u0131 saklar.<\/li>\n<li><strong>Mesaj Kal\u0131c\u0131l\u0131\u011f\u0131:<\/strong> Mesajlar\u0131n kendilerinin de kal\u0131c\u0131 olarak i\u015faretlenmesi gerekir. Bu, <code>basicPublish<\/code> metoduna <code>new AMQP.BasicProperties.Builder().deliveryMode(2).build()<\/code> gibi \u00f6zellikler ekleyerek yap\u0131l\u0131r. <code>deliveryMode(2)<\/code> de\u011feri, mesaj\u0131n disk \u00fczerine yaz\u0131laca\u011f\u0131n\u0131 ve RabbitMQ yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda bile kaybolmayaca\u011f\u0131n\u0131 belirtir. <code>deliveryMode(1)<\/code> ise non-persistent (kal\u0131c\u0131 olmayan) mesajlar i\u00e7in kullan\u0131l\u0131r ve sadece bellekte tutulur, sunucu \u00e7\u00f6k\u00fc\u015f\u00fcnde kaybolur.<\/li>\n<\/ol>\n<pre><code class=\"language-java\">\nimport com.rabbitmq.client.AMQP; \n\/\/ ... di\u011fer importlar ...\n\n\/\/ Publisher'da mesaj\u0131 kal\u0131c\u0131 hale getirme\n\/\/ channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY,\n\/\/                      new AMQP.BasicProperties.Builder()\n\/\/                          .deliveryMode(2) \/\/ 2 = persistent (kal\u0131c\u0131)\n\/\/                          .contentType(\"application\/json\")\n\/\/                          .build(),\n\/\/                      message.getBytes(StandardCharsets.UTF_8));\n\/\/ System.out.println(\" [x] Kal\u0131c\u0131 mesaj g\u00f6nderildi: '\" + message + \"'\");\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00fc\u00e7 katmanl\u0131 dayan\u0131kl\u0131l\u0131k, RabbitMQ sunucusunun beklenmedik bir \u015fekilde \u00e7\u00f6kmesi durumunda bile mesajlar\u0131n\u0131z\u0131n kaybolmamas\u0131n\u0131 garanti alt\u0131na al\u0131r ve veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flar. Ancak, kal\u0131c\u0131 mesajlar disk G\/\u00c7 (I\/O) gerektirdi\u011finden, \u00f6zellikle \u00e7ok y\u00fcksek mesaj hacimlerinde performans\u0131 bir miktar etkileyebilir. Bu nedenle, uygulaman\u0131z\u0131n gereksinimlerine (veri kayb\u0131 tolerans\u0131 vs.) g\u00f6re dikkatli bir denge kurman\u0131z ve hem dayan\u0131kl\u0131l\u0131\u011f\u0131 hem de performans\u0131 optimize etmeniz \u00f6nemlidir. Baz\u0131 durumlarda, daha d\u00fc\u015f\u00fck kal\u0131c\u0131l\u0131k modlar\u0131 se\u00e7ilebilir.<\/p>\n<h3>Mesaj Onaylama (Acknowledgements - Ack\/Nack) Mekanizmalar\u0131<\/h3>\n<p>Daha \u00f6nce de bahsetti\u011fimiz gibi, <code>basicAck<\/code> ve <code>basicNack<\/code> mesaj i\u015fleme g\u00fcvenilirli\u011finin anahtar\u0131d\u0131r. <code>autoAck: false<\/code> olarak ayarland\u0131\u011f\u0131nda, bir t\u00fcketici mesaj\u0131 ba\u015far\u0131yla i\u015fledi\u011finde <code>basicAck<\/code> ile RabbitMQ'ya bildirmelidir. Bu, RabbitMQ'nun mesaj\u0131 kuyruktan g\u00fcvenli bir \u015fekilde silebilece\u011fi anlam\u0131na gelir. E\u011fer mesaj i\u015flenemezse (\u00f6rne\u011fin bir veritaban\u0131 hatas\u0131, i\u015f mant\u0131\u011f\u0131 hatas\u0131 veya d\u0131\u015f servis ba\u011flant\u0131 sorunu nedeniyle), <code>basicNack<\/code> ile mesaj\u0131n reddedildi\u011fini bildirebiliriz. <code>basicNack<\/code>'in <code>requeue<\/code> parametresi (<code>true<\/code> veya <code>false<\/code>), mesaj\u0131n tekrar kuyru\u011fa al\u0131n\u0131p al\u0131nmayaca\u011f\u0131n\u0131 belirler. E\u011fer <code>true<\/code> ise mesaj ba\u015fka bir t\u00fcketici taraf\u0131ndan tekrar i\u015flenmek \u00fczere kuyru\u011fa d\u00f6ner. Bu, ge\u00e7ici hatalar i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r. S\u00fcrekli ba\u015far\u0131s\u0131z olan mesajlar i\u00e7in ise \"dead-letter queue\" (DLQ) mekanizmas\u0131 kullan\u0131labilir. Bir mesaj belirli say\u0131da yeniden denemeden sonra hala i\u015flenemezse, otomatik olarak bir DLQ'ya y\u00f6nlendirilir. Bu, hatal\u0131 mesajlar\u0131n ana kuyru\u011fu t\u0131kamas\u0131n\u0131 (mesaj zehirlenmesi) engeller ve manuel inceleme veya daha sonraki otomatik kurtarma i\u015flemleri i\u00e7in bir havuz sa\u011flar. DLQ'lar, sisteminizin hata tolerans\u0131n\u0131 art\u0131ran ve operasyonel karma\u015f\u0131kl\u0131\u011f\u0131 azaltan \u00e7ok de\u011ferli bir \u00f6zelliktir.<\/p>\n<div class=\"warning\">\n        Uyar\u0131: <code>basicNack<\/code> kullan\u0131rken <code>requeue<\/code> parametresini dikkatli se\u00e7in. S\u00fcrekli hata veren bir mesaj\u0131 (<code>requeue: true<\/code> ile) s\u00fcrekli kuyru\u011fa geri g\u00f6ndermek, \"mesaj zehirlenmesi\" (message poisoning) denilen duruma yol a\u00e7abilir ve t\u00fcm t\u00fcketicilerin t\u0131kanmas\u0131na neden olabilir. Bu t\u00fcr senaryolar i\u00e7in Dead Letter Exchange\/Queue (DLX\/DLQ) kullan\u0131m\u0131 \u015fartt\u0131r. DLQ, mesajlar\u0131n bir kenara konularak sorunlu durumlar\u0131n incelenmesine olanak tan\u0131r.\n    <\/div>\n<h3>Spring AMQP ile RabbitMQ Entegrasyonunu Basitle\u015ftirme<\/h3>\n<p>RabbitMQ Java istemci k\u00fct\u00fcphanesi olduk\u00e7a g\u00fc\u00e7l\u00fc olsa da, Spring ekosisteminde geli\u015ftirme yapanlar i\u00e7in Spring AMQP, RabbitMQ entegrasyonunu \u00f6nemli \u00f6l\u00e7\u00fcde basitle\u015ftirir ve geli\u015ftirme verimlili\u011fini art\u0131r\u0131r. Spring AMQP, geli\u015ftiricilerin d\u00fc\u015f\u00fck seviyeli AMQP detaylar\u0131yla (ba\u011flant\u0131 y\u00f6netimi, kanal a\u00e7ma\/kapama, mesaj onaylama) u\u011fra\u015fmak yerine i\u015f mant\u0131\u011f\u0131na odaklanmas\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, <code>@RabbitListener<\/code> anotasyonu ile mesaj dinleyicileri tan\u0131mlamay\u0131, <code>RabbitTemplate<\/code> ile mesaj g\u00f6ndermeyi ve ba\u011flant\u0131 y\u00f6netimini otomatik olarak halleder.<\/p>\n<p>\u00d6rne\u011fin, Spring Boot ile bir t\u00fcketici geli\u015ftirmek i\u00e7in projenizin <code>pom.xml<\/code> dosyas\u0131na a\u015fa\u011f\u0131daki ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 eklemeniz yeterlidir:<\/p>\n<pre><code class=\"language-xml\">\n<dependency>\n    <groupId>org.springframework.boot<\/groupId>\n    <artifactId>spring-boot-starter-amqp<\/artifactId>\n<\/dependency>\n    <\/pre>\n<p><\/code><\/p>\n<p>Ve ard\u0131ndan bir t\u00fcketici servisi a\u015fa\u011f\u0131daki gibi olu\u015fturabilirsiniz:<\/p>\n<pre><code class=\"language-java\">\nimport org.springframework.amqp.rabbit.annotation.RabbitListener;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class SpringOrderEventConsumer {\n\n    private final static String QUEUE_NAME = \"order_created_queue\";\n\n    @RabbitListener(queues = QUEUE_NAME)\n    public void receiveMessage(String orderMessage) {\n        System.out.println(\" [Spring] Mesaj al\u0131nd\u0131: '\" + orderMessage + \"'\");\n        \/\/ \u0130\u015f mant\u0131\u011f\u0131 burada. \u00d6rne\u011fin, veritaban\u0131na kay\u0131t, ba\u015fka bir servise \u00e7a\u011fr\u0131.\n        try {\n            \/\/ \u0130\u015flem s\u00fcresi sim\u00fclasyonu\n            Thread.sleep(1500); \n            System.out.println(\" [Spring] Mesaj ba\u015far\u0131yla i\u015flendi: \" + orderMessage);\n            \/\/ Spring AMQP, metod ba\u015far\u0131l\u0131 bir \u015fekilde tamamland\u0131\u011f\u0131nda otomatik ACK yapar (varsay\u0131lan olarak).\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            System.err.println(\" [Spring] Mesaj i\u015flenirken kesinti olu\u015ftu: \" + orderMessage);\n            \/\/ Hata durumunda Spring otomatik olarak NACK yap\u0131p mesaj\u0131 tekrar kuyru\u011fa g\u00f6nderebilir\n            \/\/ Veya bir Dead Letter Queue'ya y\u00f6nlendirebilir (Spring Boot konfig\u00fcrasyonuna ba\u011fl\u0131d\u0131r).\n            \/\/ E\u011fer mesaj yeniden denemeleri t\u00fckenmi\u015fse, Spring bunu DLQ'ya y\u00f6nlendirebilir.\n            throw new RuntimeException(\"Mesaj i\u015fleme hatas\u0131\", e); \/\/ Spring'in hata y\u00f6netimini tetikler\n        } catch (Exception e) {\n            System.err.println(\" [Spring] Mesaj i\u015flenirken genel hata olu\u015ftu: \" + orderMessage + \" - Hata: \" + e.getMessage());\n            throw new RuntimeException(\"Mesaj i\u015fleme hatas\u0131\", e); \/\/ Spring'in hata y\u00f6netimini tetikler\n        }\n    }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>@RabbitListener<\/code> anotasyonu sayesinde <code>SpringOrderEventConsumer<\/code> s\u0131n\u0131f\u0131, belirtilen kuyruktan otomatik olarak mesajlar\u0131 dinler. Spring Boot, gerekli ba\u011flant\u0131 ve kanal y\u00f6netimini arka planda halleder. Ayr\u0131ca, Spring AMQP mesaj d\u00f6n\u00fc\u015f tiplerine ve f\u0131rlat\u0131lan istisnalara g\u00f6re otomatik olarak ACK\/NACK mekanizmalar\u0131n\u0131 da y\u00f6netebilir, bu da geli\u015ftirme s\u00fcrecini daha da kolayla\u015ft\u0131r\u0131r. Spring AMQP'nin sa\u011flad\u0131\u011f\u0131 bu soyutlama katman\u0131 ve kolayl\u0131klar, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalarda geli\u015ftirme verimlili\u011fini art\u0131r\u0131r. Geli\u015ftiricilerin daha az boilerplate kod yazarak i\u015f mant\u0131\u011f\u0131na odaklanmas\u0131n\u0131 sa\u011flar ve RabbitMQ ile entegrasyonu standart Spring prensipleriyle uyumlu hale getirir, b\u00f6ylece tutarl\u0131 bir geli\u015ftirme deneyimi sunar.<\/p>\n<p>Bu ileri d\u00fczey konular, olay odakl\u0131 mimarinin \u00fcretim ortam\u0131nda ba\u015far\u0131l\u0131 bir \u015fekilde uygulanmas\u0131 i\u00e7in hayati \u00f6neme sahiptir. Do\u011fru yap\u0131land\u0131rma ve stratejilerle, sistemlerinizin hem g\u00fcvenilir hem de y\u00fcksek performansl\u0131 olmas\u0131n\u0131 sa\u011flayabilir, ayn\u0131 zamanda operasyonel karma\u015f\u0131kl\u0131\u011f\u0131 y\u00f6netebilirsiniz. Bu sayede, daha sa\u011flam ve gelece\u011fe haz\u0131r sistemler in\u015fa edebilirsiniz.<\/p>\n<h2>Olay Odakl\u0131 Mimari Kullan\u0131m\u0131n\u0131n Avantajlar\u0131 ve Dezavantajlar\u0131 Nelerdir?<\/h2>\n<p>Her mimari yakla\u015f\u0131m gibi, olay odakl\u0131 mimarinin de kendine \u00f6zg\u00fc avantajlar\u0131 ve dezavantajlar\u0131 bulunmaktad\u0131r. Bu dengeyi anlamak, projeniz i\u00e7in do\u011fru se\u00e7imi yapman\u0131za yard\u0131mc\u0131 olacak ve potansiyel zorluklar\u0131 \u00f6nceden g\u00f6rmenizi sa\u011flayacakt\u0131r. Olay odakl\u0131 mimari, belirli senaryolarda \u00e7ok g\u00fc\u00e7l\u00fc bir \u00e7\u00f6z\u00fcm sunarken, her durumda en iyi se\u00e7enek olmayabilir.<\/p>\n<h3>Olay Odakl\u0131 Mimari Kullan\u0131m\u0131n\u0131n Temel Avantajlar\u0131:<\/h3>\n<ul>\n<li><strong>Gev\u015fek Ba\u011fl\u0131l\u0131k (Loose Coupling):<\/strong> Servisler birbirleri hakk\u0131nda do\u011frudan bilgi sahibi olmak zorunda kalmazlar. Bir servis yaln\u0131zca yay\u0131nlad\u0131\u011f\u0131 olaylar\u0131 bilir, kimin bu olaylar\u0131 t\u00fcketece\u011fini bilmez. Bu, servislerin ba\u011f\u0131ms\u0131z olarak geli\u015ftirilmesini, test edilmesini ve da\u011f\u0131t\u0131lmas\u0131n\u0131 kolayla\u015ft\u0131r\u0131r, ayr\u0131ca sistemin genel mod\u00fclerli\u011fini art\u0131r\u0131r. Bir serviste yap\u0131lan de\u011fi\u015fiklikler, di\u011fer servisleri minimum d\u00fczeyde etkiler.<\/li>\n<li><strong>Y\u00fcksek \u00d6l\u00e7eklenebilirlik:<\/strong> Asenkron do\u011fas\u0131 sayesinde, servisler kendi h\u0131zlar\u0131nda \u00e7al\u0131\u015fabilirler. \u0130\u015f y\u00fck\u00fc artt\u0131\u011f\u0131nda, sadece ilgili t\u00fcketicilerin say\u0131s\u0131n\u0131 art\u0131rmak genellikle yeterlidir. Bu, genel sistemin kolayca yatay olarak \u00f6l\u00e7eklenebilmesini sa\u011flar ve ani trafik art\u0131\u015flar\u0131na kar\u015f\u0131 direnci art\u0131r\u0131r.<\/li>\n<li><strong>Esneklik ve Geni\u015fletilebilirlik:<\/strong> Sisteme yeni bir \u00f6zellik eklemek veya mevcut bir i\u015flevi de\u011fi\u015ftirmek genellikle daha kolayd\u0131r. Yeni bir t\u00fcketici ekleyerek mevcut olaylar\u0131 dinleyebilir veya yeni olaylar yay\u0131nlayabilirsiniz, mevcut servislerde b\u00fcy\u00fck de\u011fi\u015fiklikler yapmadan. Bu \"tak ve \u00e7al\u0131\u015ft\u0131r\" yakla\u015f\u0131m\u0131, inovasyon h\u0131z\u0131n\u0131 art\u0131r\u0131r.<\/li>\n<li><strong>Dayan\u0131kl\u0131l\u0131k ve Hata Tolerans\u0131:<\/strong> Bir servis ar\u0131zaland\u0131\u011f\u0131nda veya yava\u015flad\u0131\u011f\u0131nda, mesajlar kuyruklarda bekleyebilir ve servis tekrar \u00e7evrimi\u00e7i oldu\u011funda i\u015flenmeye devam edebilir. Bu, sistemin genel olarak daha sa\u011flam olmas\u0131n\u0131 sa\u011flar ve tek bir hata noktas\u0131n\u0131n (single point of failure) etkisini azalt\u0131r, b\u00f6ylece kesintisiz hizmet sunumuna katk\u0131da bulunur.<\/li>\n<li><strong>Yan\u0131t S\u00fcrelerinin \u0130yile\u015fmesi:<\/strong> Asenkron i\u015flemler sayesinde, kullan\u0131c\u0131ya an\u0131nda yan\u0131t verilebilirken, arka plandaki yo\u011fun i\u015flemler zamanla tamamlanabilir. Bu, \u00f6zellikle web tabanl\u0131 uygulamalarda ve mobil uygulamalarda kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir, kullan\u0131c\u0131lar\u0131n beklemek zorunda kalmamas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Ger\u00e7ek Zamanl\u0131 Veri \u0130\u015fleme:<\/strong> Olaylar an\u0131nda i\u015flenebildi\u011fi i\u00e7in, ger\u00e7ek zamanl\u0131 veri ak\u0131\u015flar\u0131, IoT sens\u00f6r verilerinin i\u015flenmesi, anl\u0131k analitik ve i\u015f zekas\u0131 uygulamalar\u0131 i\u00e7in ideal bir temel olu\u015fturur. Bu, i\u015fletmelerin daha h\u0131zl\u0131 kararlar almas\u0131na yard\u0131mc\u0131 olur.<\/li>\n<\/ul>\n<h3>Olay Odakl\u0131 Mimari Kullan\u0131m\u0131n\u0131n Potansiyel Dezavantajlar\u0131:<\/h3>\n<ul>\n<li><strong>Artan Karma\u015f\u0131kl\u0131k:<\/strong> Olay odakl\u0131 mimariler, \u00f6zellikle ba\u015flang\u0131\u00e7ta, geleneksel senkronize mimarilere g\u00f6re daha karma\u015f\u0131k olabilir. Mesaj broker'\u0131 y\u00f6netimi, olay \u015femas\u0131 tan\u0131mlar\u0131, olaylar\u0131n do\u011fru s\u0131ralamas\u0131, idempotency (ayn\u0131 olay\u0131n birden fazla i\u015flenmesi durumunda yan etki olmamas\u0131) ve hata i\u015fleme gibi konular ek \u00e7aba ve uzmanl\u0131k gerektirir.<\/li>\n<li><strong>Da\u011f\u0131t\u0131k \u0130\u015flem Y\u00f6netimi:<\/strong> Birden fazla servisin ayn\u0131 olaya tepki verdi\u011fi ve veri tutarl\u0131l\u0131\u011f\u0131n\u0131n kritik oldu\u011fu durumlarda, da\u011f\u0131t\u0131k i\u015flemlerin tutarl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flamak zorla\u015fabilir. \"Saga\" desenleri gibi \u00f6zel yakla\u015f\u0131mlar gerekebilir, bu da ek tasar\u0131m ve geli\u015ftirme maliyeti getirir.<\/li>\n<li><strong>\u0130zleme ve Hata Ay\u0131klama Zorluklar\u0131:<\/strong> Asenkron i\u015flemlerin izlenmesi ve hatalar\u0131n ay\u0131klanmas\u0131, senkronize sistemlere g\u00f6re daha zordur. Bir olay\u0131n hangi servislerden ge\u00e7ti\u011fini ve nerede bir hata olu\u015ftu\u011funu belirlemek i\u00e7in geli\u015fmi\u015f izleme (distributed tracing) ara\u00e7lar\u0131na (\u00f6rne\u011fin, OpenTelemetry, Jaeger) ihtiya\u00e7 duyulabilir.<\/li>\n<li><strong>Olay Versiyonlama:<\/strong> Olay \u015femalar\u0131 zamanla de\u011fi\u015febilir. Bu de\u011fi\u015fiklikleri y\u00f6netmek (eski t\u00fcketicilerin yeni olay \u015femalar\u0131n\u0131 anlamas\u0131 veya tam tersi) dikkatli bir planlama ve geriye d\u00f6n\u00fck uyumluluk stratejileri (backward compatibility) gerektirir.<\/li>\n<li><strong>Mesaj S\u0131ralamas\u0131 Garantisi:<\/strong> \u00c7o\u011fu mesaj kuyru\u011fu sistemi, genel bir mesaj s\u0131ralamas\u0131 garantisi vermez (yani, mesajlar\u0131n yay\u0131nlanma s\u0131ras\u0131yla i\u015flenme s\u0131ras\u0131 ayn\u0131 olmayabilir). Belirli bir s\u0131ralama gerekiyorsa, bunu sa\u011flamak i\u00e7in ek mekanizmalar (\u00f6rne\u011fin, tek kuyruklu t\u00fcketiciler, olaylara zaman damgas\u0131 ekleme veya Kafka gibi partition'l\u0131 sistemler) tasarlamak gerekebilir.<\/li>\n<li><strong>Kuyruk Zehirlenmesi (Message Poisoning):<\/strong> S\u00fcrekli olarak hata veren bir mesaj\u0131n kuyrukta d\u00f6n\u00fcp durmas\u0131 ve t\u00fcketicilerin di\u011fer mesajlar\u0131 i\u015flemesini engellemesi durumudur. Dead Letter Queue (DLQ) gibi mekanizmalar bu durumu y\u00f6netmek i\u00e7in elzemdir.<\/li>\n<\/ul>\n<p>Sonu\u00e7 olarak, olay odakl\u0131 mimari, do\u011fru kullan\u0131ld\u0131\u011f\u0131nda modern ve \u00f6l\u00e7eklenebilir sistemler olu\u015fturmak i\u00e7in g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r. Ancak, getirdi\u011fi karma\u015f\u0131kl\u0131klar\u0131n ve zorluklar\u0131n fark\u0131nda olmak ve bunlar\u0131 y\u00f6netmek i\u00e7in uygun ara\u00e7 ve stratejileri benimsemek \u00f6nemlidir. K\u00fc\u00e7\u00fck ve basit projeler i\u00e7in gere\u011finden fazla olabilirken, b\u00fcy\u00fck, da\u011f\u0131t\u0131k ve y\u00fcksek performans gerektiren sistemler i\u00e7in vazge\u00e7ilmez bir \u00e7\u00f6z\u00fcm sunar. Bu nedenle, projenizin \u00f6zel ihtiya\u00e7lar\u0131n\u0131 ve kaynaklar\u0131n\u0131 dikkatlice de\u011ferlendirerek bu mimariyi se\u00e7mek en do\u011fru yakla\u015f\u0131m olacakt\u0131r. \u0130yi tasarlanm\u0131\u015f bir olay odakl\u0131 sistem, uzun vadede daha az bak\u0131m gerektirecek ve daha esnek bir yap\u0131 sunacakt\u0131r.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin temel prensiplerini, uygulan\u0131\u015f\u0131n\u0131 ve ger\u00e7ek d\u00fcnya senaryolar\u0131ndaki kullan\u0131m\u0131n\u0131 derinlemesine inceledik. Geleneksel mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015fmak, sistemlerinizin gev\u015fek ba\u011fl\u0131, \u00f6l\u00e7eklenebilir ve dayan\u0131kl\u0131 olmas\u0131n\u0131 sa\u011flamak i\u00e7in olay odakl\u0131 yakla\u015f\u0131m\u0131n ne kadar g\u00fc\u00e7l\u00fc bir ara\u00e7 oldu\u011funu g\u00f6rd\u00fck. RabbitMQ'nun mesaj broker\u0131 olarak bu mimaride nas\u0131l kritik bir rol oynad\u0131\u011f\u0131n\u0131, Java ile olay yay\u0131nc\u0131lar\u0131 ve t\u00fcketicileri nas\u0131l geli\u015ftirebilece\u011fimizi ad\u0131m ad\u0131m ele ald\u0131k. Ayr\u0131ca, e-ticaret sipari\u015f s\u00fcreci gibi somut bir \u00f6rnekle olay odakl\u0131 mimarinin ger\u00e7ek d\u00fcnyadaki faydalar\u0131n\u0131 g\u00f6sterdik ve mesaj dayan\u0131kl\u0131l\u0131\u011f\u0131, ack\/nack mekanizmalar\u0131 ve Spring AMQP gibi ileri d\u00fczey konulara de\u011findik. Olay odakl\u0131 mimarinin avantajlar\u0131n\u0131 ve potansiyel dezavantajlar\u0131n\u0131 da de\u011ferlendirerek, projeniz i\u00e7in bilin\u00e7li kararlar vermenize yard\u0131mc\u0131 olmay\u0131 hedefledik.<\/p>\n<p>Unutmay\u0131n ki, modern yaz\u0131l\u0131m sistemleri s\u00fcrekli evrilmekte ve olay odakl\u0131 mimari, bu evrimin \u00f6nemli bir par\u00e7as\u0131d\u0131r. Do\u011fru tasar\u0131m ve uygulama ile, daha esnek, bak\u0131m\u0131 kolay ve gelece\u011fe haz\u0131r sistemler in\u015fa edebilirsiniz. Bu teknolojileri anlamak ve ustala\u015fmak, yaz\u0131l\u0131m geli\u015ftirme kariyerinizde size \u00f6nemli avantajlar sa\u011flayacakt\u0131r ve sizi da\u011f\u0131t\u0131k sistemler d\u00fcnyas\u0131nda daha yetkin k\u0131lacakt\u0131r. Olay odakl\u0131 mimari, s\u00fcrekli de\u011fi\u015fen i\u015f ihtiya\u00e7lar\u0131na cevap verebilen ve y\u00fcksek performans gerektiren uygulamalar i\u00e7in modern bir \u00e7\u00f6z\u00fcm sunar.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ol>\n<li>\n<h4>Olay Odakl\u0131 Mimari (EDA) her proje i\u00e7in uygun mudur?<\/h4>\n<p>Hay\u0131r, her proje i\u00e7in uygun de\u011fildir. K\u00fc\u00e7\u00fck, basit ve monolitik uygulamalar i\u00e7in geleneksel istek-cevap mimarileri daha az karma\u015f\u0131kl\u0131k sunar ve genellikle yeterlidir. EDA, \u00f6zellikle mikroservisler, da\u011f\u0131t\u0131k sistemler, y\u00fcksek \u00f6l\u00e7eklenebilirlik, esneklik, hata tolerans\u0131 ve ger\u00e7ek zamanl\u0131 veri i\u015fleme gereksinimleri olan karma\u015f\u0131k ve b\u00fcy\u00fck projelerde parlar. Projenizin \u00f6l\u00e7e\u011fi ve karma\u015f\u0131kl\u0131\u011f\u0131 artt\u0131k\u00e7a EDA'n\u0131n faydalar\u0131 daha belirgin hale gelir.<\/p>\n<\/li>\n<li>\n<h4>RabbitMQ yerine ba\u015fka hangi mesaj brokerlar\u0131 kullan\u0131labilir?<\/h4>\n<p>RabbitMQ pop\u00fcler bir se\u00e7enek olsa da, Apache Kafka, Apache ActiveMQ, Google Cloud Pub\/Sub, Amazon SQS\/SNS ve Azure Service Bus gibi ba\u015fka g\u00fc\u00e7l\u00fc mesaj brokerlar\u0131 da bulunmaktad\u0131r. Se\u00e7im, projenizin \u00f6zel gereksinimlerine (y\u00fcksek throughput, kal\u0131c\u0131l\u0131k garantileri, ekosistem entegrasyonu, bulut hizmetleri ba\u011f\u0131ml\u0131l\u0131\u011f\u0131, veri ak\u0131\u015f\u0131 analizi yetenekleri vb.) ba\u011fl\u0131d\u0131r. Kafka, \u00f6zellikle y\u00fcksek hacimli ak\u0131\u015f verisi i\u015fleme ve event sourcing i\u00e7in s\u0131k\u00e7a tercih edilirken, RabbitMQ daha \u00e7ok genel ama\u00e7l\u0131 mesaj kuyruklama, olay y\u00f6nlendirme ve RPC benzeri senaryolar i\u00e7in kullan\u0131l\u0131r.<\/p>\n<\/li>\n<li>\n<h4>Olaylar\u0131n s\u0131ralamas\u0131 (ordering) kritikse ne yapmal\u0131y\u0131m?<\/h4>\n<p>\u00c7o\u011fu mesaj broker\u0131, mesajlar\u0131n i\u015flenmesinde kesin bir s\u0131ralama garantisi vermez (\u00f6zellikle birden fazla t\u00fcketici oldu\u011funda). E\u011fer olaylar\u0131n s\u0131ralamas\u0131 kritikse, bunu sa\u011flamak i\u00e7in ek stratejiler izlemelisiniz:<\/p>\n<ul>\n<li>Ayn\u0131 varl\u0131\u011fa ait olaylar\u0131 (\u00f6rne\u011fin, belirli bir kullan\u0131c\u0131n\u0131n t\u00fcm sipari\u015f olaylar\u0131) tek bir kuyru\u011fa veya Kafka'da tek bir partition'a y\u00f6nlendirmek.<\/li>\n<li>Olaylara zaman damgalar\u0131 (timestamp) ekleyerek t\u00fcketicide s\u0131ralama mant\u0131\u011f\u0131 uygulamak ve gerekirse olaylar\u0131 yeniden s\u0131ralamak.<\/li>\n<li>Kuyruk ba\u015f\u0131na tek t\u00fcketici (single consumer per queue) desenini kullanarak s\u0131ralamay\u0131 garanti alt\u0131na almak, ancak bu \u00f6l\u00e7eklenebilirli\u011fi s\u0131n\u0131rlayabilir.<\/li>\n<\/ul>\n<p>            Bu t\u00fcr senaryolarda tasar\u0131m\u0131n\u0131za \u00f6zel dikkat g\u00f6stermeniz ve potansiyel performans etkilerini de\u011ferlendirmeniz gerekmektedir.<\/p>\n<\/li>\n<li>\n<h4>Dead Letter Queue (DLQ) nedir ve neden \u00f6nemlidir?<\/h4>\n<p>Dead Letter Queue (DLQ), i\u015flenemeyen, belirli ko\u015fullar\u0131 kar\u015f\u0131layamayan veya bir t\u00fcketici taraf\u0131ndan reddedilen (nack'lenen) mesajlar\u0131n y\u00f6nlendirildi\u011fi \u00f6zel bir kuyruktur. Bir mesaj, bir t\u00fcketici taraf\u0131ndan belirli say\u0131da denemeye ra\u011fmen i\u015flenemezse (\u00f6rne\u011fin, uygulama hatas\u0131, ge\u00e7ersiz veri), zaman a\u015f\u0131m\u0131na u\u011frarsa veya manuel olarak reddedilirse (basicNack ile), DLQ'ya g\u00f6nderilebilir. DLQ'lar, hatal\u0131 mesajlar\u0131n ana kuyru\u011fu t\u0131kamas\u0131n\u0131 (mesaj zehirlenmesi) engeller ve bu mesajlar\u0131n daha sonra manuel olarak incelenmesi, hatalar\u0131n giderilmesi veya otomatik yeniden deneme mekanizmalar\u0131yla kurtar\u0131lmas\u0131 i\u00e7in bir f\u0131rsat sunar. Sisteminizin dayan\u0131kl\u0131l\u0131\u011f\u0131, hata y\u00f6netimi ve operasyonel g\u00f6r\u00fcn\u00fcrl\u00fc\u011f\u00fc i\u00e7in kritik bir bile\u015fendir.<\/p>\n<\/li>\n<li>\n<h4>Olay Odakl\u0131 Mimari ile veri tutarl\u0131l\u0131\u011f\u0131 nas\u0131l sa\u011flan\u0131r?<\/h4>\n<p>EDA'da veri tutarl\u0131l\u0131\u011f\u0131, da\u011f\u0131t\u0131k i\u015flemler ve nihai tutarl\u0131l\u0131k (eventual consistency) kavramlar\u0131yla y\u00f6netilir. Senkronize, anl\u0131k tutarl\u0131l\u0131k garantisi yerine, sistemdeki t\u00fcm bile\u015fenlerin bir olaya tepki verip kendi verilerini g\u00fcncelledikten sonra tutarl\u0131l\u0131\u011fa ula\u015faca\u011f\u0131 kabul edilir. Bir i\u015flem birden fazla servisi etkiliyorsa, \"Saga\" desenleri gibi yakla\u015f\u0131mlar kullan\u0131labilir. Saga, bir dizi yerel i\u015flemin s\u0131ras\u0131n\u0131 koordine ederek da\u011f\u0131t\u0131k bir i\u015flemi y\u00f6netir. Her yerel i\u015flem ba\u015far\u0131l\u0131 olursa bir sonraki ad\u0131ma ge\u00e7ilir; aksi takdirde, \u00f6nceki i\u015flemleri geri alan telafi edici i\u015flemler (compensating transactions) ba\u015flat\u0131l\u0131r. Bu yakla\u015f\u0131m, sistem genelinde veri tutarl\u0131l\u0131\u011f\u0131n\u0131 nihai olarak sa\u011flarken, senkronize kilitlenme ve performans darbo\u011fazlar\u0131ndan ka\u00e7\u0131nman\u0131z\u0131 sa\u011flar. Transactional outbox pattern gibi \u00e7\u00f6z\u00fcmler de yay\u0131nc\u0131n\u0131n veri taban\u0131 i\u015flemi ile olay yay\u0131nlamay\u0131 atomik hale getirerek veri tutarl\u0131l\u0131\u011f\u0131n\u0131 art\u0131rabilir.<\/p>\n<\/li>\n<\/ol>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi.&hellip;","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":[1408],"tags":[],"class_list":{"0":"post-32944","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-java","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>Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber<\/title>\n<meta name=\"description\" content=\"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.\" \/>\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\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber\" \/>\n<meta property=\"og:description\" content=\"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-27T13:33:47+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=\"38 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber\",\"datePublished\":\"2025-10-27T13:33:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\"},\"wordCount\":6650,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Java\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\",\"name\":\"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-27T13:33:47+00:00\",\"description\":\"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber\"}]},{\"@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":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber","description":"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.","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\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/","og_locale":"tr_TR","og_type":"article","og_title":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber","og_description":"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.","og_url":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-27T13:33:47+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"38 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber","datePublished":"2025-10-27T13:33:47+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/"},"wordCount":6650,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Java"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/","url":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/","name":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-27T13:33:47+00:00","description":"Modern yaz\u0131l\u0131m mimarilerinde esneklik, \u00f6l\u00e7eklenebilirlik ve y\u00fcksek performans elde etmek, giderek karma\u015f\u0131kla\u015fan sistemlerin temel gereksinimlerinden biri haline geldi. Peki, geleneksel istek-cevap tabanl\u0131 mimarilerin s\u0131n\u0131rlamalar\u0131n\u0131 a\u015farak, sistemlerinizin daha h\u0131zl\u0131 ve g\u00fcvenilir ileti\u015fim kurmas\u0131n\u0131 nas\u0131l sa\u011flayabilirsiniz? Bu makalede, Java ve RabbitMQ kullanarak olay odakl\u0131 mimarinin (EDA) g\u00fcc\u00fcn\u00fc ke\u015ffedecek, da\u011f\u0131t\u0131k sistemlerinizin ileti\u015fimini d\u00f6n\u00fc\u015ft\u00fcrecek pratik bilgiler edineceksiniz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/java-ve-rabbitmq-ile-olay-odakli-mimari-kapsamli-rehber\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Java ve RabbitMQ ile Olay Odakl\u0131 Mimari: Kapsaml\u0131 Rehber"}]},{"@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\/32944","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=32944"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32944\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32944"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32944"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32944"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}