﻿
{"id":13676,"date":"2020-02-25T17:25:24","date_gmt":"2020-02-25T17:25:24","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=13676"},"modified":"2020-02-25T17:25:24","modified_gmt":"2020-02-25T17:25:24","slug":"rabbitmq-akilli-kuyruk-mimarisi-nasil-tasarlanir","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/rabbitmq-akilli-kuyruk-mimarisi-nasil-tasarlanir\/","title":{"rendered":"RabbitMQ &#8211; Ak\u0131ll\u0131 Kuyruk Mimarisi Nas\u0131l Tasarlan\u0131r?"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bir \u00f6nceki <a href=\"https:\/\/www.gencayyildiz.com\/blog\/rabbitmq-basitce-kuyruga-mesaj-gonderme-ve-okuma\/\" rel=\"noopener noreferrer\" target=\"_blank\">RabbitMQ \u2013 Basit\u00e7e Kuyru\u011fa Mesaj G\u00f6nderme ve Okuma<\/a> ba\u015fl\u0131kl\u0131 yaz\u0131mda RabbitMQ servisine mesaj g\u00f6nderme ve g\u00f6nderilen mesajlar\u0131 okuma eylemlerini temel d\u00fczeyde incelemi\u015f bulunmaktay\u0131z. Bu i\u00e7eri\u011fimizde ise kuyruk mimarisini daha da ak\u0131ll\u0131 hale nas\u0131l getirebilece\u011fimizi orta \u015feker bir ger\u00e7ek hayat projesi \u00fczerinden konu\u015faca\u011f\u0131z.<\/p>\n<h3>Ak\u0131ll\u0131 Kuyruk Mimarisi Nedir?<\/h3>\n<p>Bir kuyruk mimarisinin ak\u0131ll\u0131 olabilmesi i\u00e7in, <em>(1)edindi\u011fi mesajlar\u0131n g\u00fcvenli bir \u015fekilde tutulup<\/em>, <em>(2)e\u015fit bir da\u011f\u0131l\u0131mla t\u00fcketilmesi<\/em> ve t\u00fcm bu i\u015flemler neticesinde sunucunun <em>(3)mesaj\u0131n i\u015flendi\u011fine dair haberdar edilmesi<\/em> gerekmektedir. \u0130\u015fte b\u00f6yle bir yap\u0131lanma ak\u0131ll\u0131 kuyruk mimarisi olarak nitelendirilebilmektedir.<\/p>\n<p>Bu a\u00e7\u0131klamadan \u00e7\u0131kard\u0131\u011f\u0131m\u0131z sonu\u00e7 \u015fudur ki bir kuyruk yap\u0131s\u0131n\u0131n ak\u0131ll\u0131 olabilmesi i\u00e7in a\u015fa\u011f\u0131daki \u00f6zellikleri uyguluyor olmas\u0131 gerekmektedir.<\/p>\n<ul>\n<li><strong>Mesajlar\u0131n Dayan\u0131kl\u0131l\u0131\u011f\u0131(Message Durability)<\/strong><br \/>\n<blockquote><p>(1)&#8230;edindi\u011fi mesajlar\u0131n g\u00fcvenli bir \u015fekilde tutulup&#8230;<\/p><\/blockquote>\n<p>RabbitMQ instance&#8217;\u0131na g\u00f6nderilen mesajlar\u0131n g\u00fcvenli\u011fini sa\u011flayarak olas\u0131 restart durumlar\u0131nda kal\u0131c\u0131l\u0131\u011f\u0131 korumak i\u00e7in <em><strong>Publisher<\/strong><\/em> ilgili mesaj\u0131 g\u00f6ndermeden \u00f6nce mesaj g\u00fcvenirlili\u011fini sa\u011flamal\u0131d\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            ConnectionFactory factory = new ConnectionFactory();\r\n            factory.Uri = new Uri(&quot;amqp:\/\/hkhjerrt:hcqiavAqll6-co4abXnSqUBh_hHifz-Z@hornet.rmq.cloudamqp.com\/hkhjerrt&quot;);\r\n\r\n            using (IConnection connection = factory.CreateConnection())\r\n            using (IModel channel = connection.CreateModel())\r\n            {\r\n                channel.QueueDeclare(&quot;iskuyrugu&quot;, durable: true, false, false, null);\r\n                for (int i = 1; i &lt;= 100; i++)\r\n                {\r\n                    byte&#x5B;] bytemessage = Encoding.UTF8.GetBytes($&quot;is - {i}&quot;);\r\n\r\n                    IBasicProperties properties = channel.CreateBasicProperties();\r\n                    properties.Persistent = true;\r\n\r\n                    channel.BasicPublish(exchange: &quot;&quot;, routingKey: &quot;iskuyrugu&quot;, basicProperties: properties, body: bytemessage);\r\n                }\r\n            }\r\n        }\r\n<\/pre>\n<p>Bunun i\u00e7in yukar\u0131daki kod blo\u011fundaki 9. sat\u0131rda oldu\u011fu gibi &#8216;durable&#8217; parametresi true olarak ayarlan\u0131r ve tan\u0131mlanan kuyruk sa\u011flamla\u015ft\u0131r\u0131l\u0131r. Ayriyetten 14 &#8211; 15. sat\u0131rlar aras\u0131nda bir &#8216;IBasicProperties&#8217; t\u00fcr\u00fcnden nesne olu\u015fturulur ve Persistent \u00f6zelli\u011fine true de\u011feri atanarak RabbitMQ&#8217;da fiziksel kayda al\u0131n\u0131r ve kal\u0131c\u0131l\u0131\u011f\u0131 sa\u011flan\u0131r. B\u00f6ylece mesaj g\u00fcvenli\u011fide sa\u011flamla\u015ft\u0131r\u0131lm\u0131\u015f olur. 17. sat\u0131rda ise &#8216;basicProperties&#8217; parametresine ilgili property verilerek mesaj\u0131m\u0131z g\u00fcvenli bir \u015fekilde kuyru\u011fa g\u00f6nderilir.<\/p>\n<\/li>\n<li><strong>E\u015fit Da\u011f\u0131l\u0131m(Fair Dispatch)<\/strong><br \/>\n<blockquote><p>&#8230;(2)e\u015fit bir da\u011f\u0131l\u0131mla t\u00fcketilmesi&#8230;<\/p><\/blockquote>\n<p>Bir kuyru\u011fu t\u00fcketmek i\u00e7in birden fazla consumer olabilir. B\u00f6yle bir durumda t\u00fcm consumerlara mesajlar e\u015fit da\u011f\u0131t\u0131lmal\u0131d\u0131r. Aksi taktirde i\u015flemci g\u00fcc\u00fc vs. gibi donan\u0131msal \u00f6zellikleri daha a\u011f\u0131r basan consumerlar k\u0131sa zamanda \u00e7ok mesaj i\u015fleyebildikleri i\u00e7in daha yo\u011fun \u00e7al\u0131\u015fmak zorunda kalabilirler.<\/p>\n<p><strong>Consumer<\/strong>;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            ConnectionFactory factory = new ConnectionFactory();\r\n            factory.Uri = new Uri(&quot;amqp:\/\/hkhjerrt:hcqiavAqll6-co4abXnSqUBh_hHifz-Z@hornet.rmq.cloudamqp.com\/hkhjerrt&quot;);\r\n\r\n            using (IConnection connection = factory.CreateConnection())\r\n            using (IModel channel = connection.CreateModel())\r\n            {\r\n                channel.QueueDeclare(&quot;iskuyrugu&quot;, durable: true, false, false, null);\r\n                channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);\r\n\r\n                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);\r\n                channel.BasicConsume(&quot;iskuyrugu&quot;, false, consumer);\r\n                consumer.Received += (sender, e) =&gt;\r\n                {\r\n                    Thread.Sleep(int.Parse(args&#x5B;0]));\r\n                    Console.WriteLine(Encoding.UTF8.GetString(e.Body) + &quot; al\u0131nd\u0131&quot;);\r\n                    channel.BasicAck(e.DeliveryTag, false);\r\n                };\r\n                Console.Read();\r\n            }\r\n        }\r\n<\/pre>\n<p>Yukar\u0131daki \u00f6rnek kod blo\u011funda bir consumer \u00e7al\u0131\u015fmas\u0131 yap\u0131lm\u0131\u015ft\u0131r. 10. sat\u0131ra g\u00f6z atarsan\u0131z e\u011fer &#8216;BasicQos&#8217; metodu ile <strong><em>port \u00f6nceli\u011fi<\/em><\/strong> anlam\u0131na gelen <strong><em>QoS<\/em><\/strong> servisi ile consumer \u00f6nceli\u011fi e\u015fitlenmekte ve b\u00f6ylece e\u015fit da\u011f\u0131l\u0131m sa\u011flanmaktad\u0131r.<\/p>\n<p>&#8216;BasicQos&#8217; metodunun;<\/p>\n<ul>\n<li><em style=\"color:purple\">prefetchSize parametresi<\/em> : Mesaj boyutunu ifade eder. 0(s\u0131f\u0131r) diyerek ilgilenmedi\u011fimizi belirtiyoruz.<\/li>\n<li><em style=\"color:purple\">prefetchCount parametresi<\/em> : Da\u011f\u0131t\u0131m adetini ifade eder.<\/li>\n<li><em style=\"color:purple\">global parametresi<\/em> : true ise, t\u00fcm consumerlar\u0131n ayn\u0131 anda <em>prefetchCount<\/em> parametresinde belirtilen de\u011fer kadar mesaj t\u00fcketebilece\u011fini ifade eder. false de\u011feri ise, her bir consumer\u0131n bir i\u015fleme s\u00fcresinde di\u011fer consumerlardan ba\u011f\u0131ms\u0131z bir \u015fekilde ka\u00e7 mesaj al\u0131p i\u015fleyece\u011fini belirtir.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Mesajlar\u0131n Al\u0131nd\u0131 Haberi(Message Acknowledgement)<\/strong><br \/>\n<blockquote><p>&#8230;(3)mesaj\u0131n i\u015flendi\u011fine dair haberdar edilmesi&#8230;<\/p><\/blockquote>\n<p>Kuyruktaki mesaj consumer taraf\u0131ndan ba\u015far\u0131yla i\u015flendikten sonra sunucu bilgilendirilmelidir. Yukar\u0131da &#8220;E\u015fit Da\u011f\u0131l\u0131m&#8221;a verilen \u00f6rnek kod blo\u011fundaki 18. sat\u0131rda &#8216;BasicAck&#8217; fonksiyonu ile bu i\u015flemi ger\u00e7ekle\u015ftirerek kuyruktan mesaj\u0131n silinmesi sa\u011flanmaktad\u0131r.\n<\/li>\n<\/ul>\n<h3>Test Edelim<\/h3>\n<p>Yukar\u0131daki yapt\u0131\u011f\u0131m\u0131z \u00e7al\u0131\u015fmaya dikkat ederseniz, publisher her \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda 100 adet mesaj\u0131 kuyru\u011fa iletmekte ve bunun yan\u0131nda consumer ise aya\u011fa kald\u0131r\u0131l\u0131rken g\u00f6nderilen arg\u00fcmandaki say\u0131sal de\u011fer kadar s\u00fcreci durdurarak i\u015flemektedir. Dolay\u0131s\u0131yla bu in\u015fa neticesinde a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi anlaml\u0131 bir kuyruk mimarisinin neticesiyle kar\u015f\u0131la\u015fmaktay\u0131z.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/RabbitMQ-Ak\u0131ll\u0131-Kuyruk-Mimarisi-Nas\u0131l-Tasarlan\u0131r.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/RabbitMQ-Ak\u0131ll\u0131-Kuyruk-Mimarisi-Nas\u0131l-Tasarlan\u0131r.gif\" alt=\"RabbitMQ - Ak\u0131ll\u0131 Kuyruk Mimarisi Nas\u0131l Tasarlan\u0131r?\" width=\"800\" height=\"470\" class=\"aligncenter size-full wp-image-13718\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere her bir consumer verilen de\u011fer kadar saniye aral\u0131\u011f\u0131nda bir mesaj t\u00fcketmektedir.<\/p>\n<p>Vee b\u00f6ylece bir RabbitMQ servisini kullanan uygulamada ak\u0131ll\u0131 kuyruk mimarisinin nas\u0131l ve nelere dikkat edilerek tasarland\u0131\u011f\u0131n\u0131 incelemi\u015f ve \u00f6rneklendirmi\u015f olduk. Vakit ay\u0131r\u0131p okudu\u011funuz i\u00e7in te\u015fekk\u00fcr ederim \ud83d\ude42<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek uygulamay\u0131 indirmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/RabbitMQExample.rar\">buraya<\/a> t\u0131klay\u0131n\u0131z.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bir \u00f6nceki RabbitMQ \u2013 Basit\u00e7e Kuyru\u011fa Mesaj G\u00f6nderme ve Okuma ba\u015fl\u0131kl\u0131 yaz\u0131mda RabbitMQ servisine mesaj g\u00f6nderme ve g\u00f6nderilen mesajlar\u0131 okuma eylemlerini temel d\u00fczeyde incelemi\u015f bulunmaktay\u0131z. Bu i\u00e7eri\u011fimizde ise kuyruk mimarisini daha da ak\u0131ll\u0131&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":13404,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3156],"tags":[3213,3209,3210,3214,3211,3207,3212,3208,3215,3216,3217,3158],"class_list":["post-13676","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rabbitmq","tag-akilli-kuyruk-mimarisi","tag-esit-dagilim","tag-fair-dispatch","tag-ibasicproperties","tag-mesajlarin-alindi-haberi","tag-mesajlarin-dayanikliligi","tag-message-acknowledgement","tag-message-durability","tag-port-onceligi","tag-qos","tag-quality-of-service","tag-rabbitmq"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=13676"}],"version-history":[{"count":45,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13676\/revisions"}],"predecessor-version":[{"id":13723,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13676\/revisions\/13723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/13404"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=13676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=13676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=13676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}