{"id":1181,"date":"2011-06-16T19:41:33","date_gmt":"2011-06-16T18:41:33","guid":{"rendered":"http:\/\/soci.hu\/blog\/?p=1181"},"modified":"2011-06-16T19:43:50","modified_gmt":"2011-06-16T18:43:50","slug":"gondolatok-a-queue-alapu-kliens-szerviz-kommunikaciohoz","status":"publish","type":"post","link":"https:\/\/soci.hu\/blog\/index.php\/2011\/06\/16\/gondolatok-a-queue-alapu-kliens-szerviz-kommunikaciohoz\/","title":{"rendered":"Gondolatok a queue alap\u00fa kliens-szerviz kommunik\u00e1ci\u00f3hoz"},"content":{"rendered":"<p>Az el\u0151z\u0151 post kommentjei alapj\u00e1n (amit nagyon k\u00f6sz\u00f6n\u00f6k mindenkinek) nem kaptam sok b\u00e1tor\u00edt\u00e1st az aszinkron, queue alap\u00fa, k\u00e9r\u00e9s-v\u00e1laszt k\u00fcl\u00f6nv\u00e1laszt\u00f3 gazdag kliens &#8211; szerviz kommunik\u00e1ci\u00f3hoz, \u00fagy t\u0171nik senki nem csin\u00e1lt ilyet, \u00edgy nem akarok \u00fatt\u00f6r\u0151 lenni a t\u00e9m\u00e1ban.<br \/>\nEhhez m\u00e9g hozz\u00e1j\u00e1rul, hogy h\u00e9tv\u00e9g\u00e9n m\u00e9regettem az MSMQ teljes\u00edtm\u00e9ny\u00e9t. Az\u00e9rt ezt, mert a WCF is erre \u00e9p\u00edt, \u00e9s pl. az NServiceBus is.<\/p>\n<p>A tesztk\u00f3d 1.5kByteos \u00fczeneteket rak \u00e1t egyik sorb\u00f3l a m\u00e1sikba. Az \u00f6tlet <a href=\"http:\/\/ayende.com\/blog\/4251\/what-am-i-missing-msmq-perf-issue\">innen<\/a> j\u00f6tt, csak t\u00f6bbsz\u00e1las\u00edtottam.<\/p>\n<p>A tesztk\u00f3d:<\/p>\n<p>using System;<br \/>\nusing System.Diagnostics;<br \/>\nusing System.Messaging;<br \/>\nusing System.Threading;<\/p>\n<p>namespace MsmqTran<br \/>\n{<br \/>\n    class Program<br \/>\n    {<br \/>\n        private const int NumberOfTests = 1000;<br \/>\n        private const int MaxDop = 10;<br \/>\n        private static readonly ManualResetEvent[] WaitForEmpty = new ManualResetEvent[MaxDop];<\/p>\n<p>        static void Main()<br \/>\n        {<br \/>\n            var q1 = new MessageQueue(@&#8221;.\\private$\\test_queue1&#8243;);<br \/>\n            var q2 = new MessageQueue(@&#8221;.\\private$\\test_queue2&#8243;);<\/p>\n<p>            Console.WriteLine(&#8220;Filling source queue&#8230;&#8221;);<br \/>\n            var b = new byte[1500];<br \/>\n            using (var msmqTx = new MessageQueueTransaction())<br \/>\n            {<br \/>\n                msmqTx.Begin();<br \/>\n                for (int i = 0; i < NumberOfTests; i++)\n                {\n                    q1.Send(b, msmqTx);\n                }\n                msmqTx.Commit();\n            }\n\n            q2.Purge();\n            Console.WriteLine(\"Starting to move data from source queue to destination queue\");\n\n            var sp = Stopwatch.StartNew();\n\n            for (int i = 0; i < MaxDop; i++)\n            {\n                WaitForEmpty[i] = new ManualResetEvent(false);\n                ThreadPool.QueueUserWorkItem(o => ProcessMsg(q1, q2, (ManualResetEvent)o), WaitForEmpty[i]);<br \/>\n            }<\/p>\n<p>            WaitHandle.WaitAll(WaitForEmpty);<\/p>\n<p>            Console.WriteLine(&#8220;Duration: {0}ms, throughput: {1:F0} messages\/s&#8221;, sp.ElapsedMilliseconds, 1000.0 * NumberOfTests \/ sp.ElapsedMilliseconds);<br \/>\n        }<\/p>\n<p>        private static void ProcessMsg(MessageQueue q1, MessageQueue q2, ManualResetEvent w)<br \/>\n        {<br \/>\n            while (true)<br \/>\n            {<br \/>\n                using (var msmqTx = new MessageQueueTransaction())<br \/>\n                {<br \/>\n                    msmqTx.Begin();<\/p>\n<p>                    Message message;<br \/>\n                    try<br \/>\n                    {<br \/>\n                        message = q1.Receive(TimeSpan.FromMilliseconds(0), msmqTx);<br \/>\n                    }<br \/>\n                    catch (MessageQueueException e)<br \/>\n                    {<br \/>\n                        Console.WriteLine(e);<br \/>\n                        w.Set();<br \/>\n                        break;<br \/>\n                    }<\/p>\n<p>                    q2.Send(message, msmqTx);<\/p>\n<p>                    msmqTx.Commit();<br \/>\n                }<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n}<\/p>\n<p>A g\u00e9pemen 50 tran\/sec-kel megy 1 sz\u00e1lon, \u00e9s 200 f\u00f6l\u00e9 nem nagyon megy. J\u00f3, ez laptop, de rel\u00e1ci\u00f3s adatb\u00e1ziskezel\u0151vel (sql server \u00e9s oracle is fut a g\u00e9pen) t\u00f6bb ezer tran\/seccel mennek a dolgok. Sz\u00f3val ez el\u00e9g g\u00e1zosan lass\u00fa. Emellett cs\u00fanya le\u00e1ll\u00e1sokr\u00f3l is \u00edrnak a blogokban, amikor be\u00e1ll az msmq.<\/p>\n<p>Marad a aszinkron\u00edtott WCF egyel\u0151re, csak a szerverr\u0151l visszafel\u00e9 h\u00edv\u00e1sokat tervezem queue alapon megcsin\u00e1lni, WCF msmq bindinggal. \u00cdgy tudom \u00e9rtes\u00edteni az appokat polling n\u00e9lk\u00fcl. Erre 3 okom van most:<br \/>\n1. Az <a href=\"http:\/\/martinfowler.com\/eaaCatalog\/pessimisticOfflineLock.html\">offline (disconnected) pessimistic lock<\/a> felold\u00f3dott, lehet szerkeszteni valamit.<br \/>\n2. Friss\u00edteni kell a kliens cache-ben valamit.<br \/>\n3. Email jelleg\u0171 \u00fczenetk\u00fcld\u00e9s az appok k\u00f6z\u00f6tt.<\/p>\n<p>K\u00f6sz\u00f6n\u00f6m m\u00e9g egyszer az \u00e9p\u00edt\u0151 javaslatokat.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Az el\u0151z\u0151 post kommentjei alapj\u00e1n (amit nagyon k\u00f6sz\u00f6n\u00f6k mindenkinek) nem kaptam sok b\u00e1tor\u00edt\u00e1st az aszinkron, queue alap\u00fa, k\u00e9r\u00e9s-v\u00e1laszt k\u00fcl\u00f6nv\u00e1laszt\u00f3 gazdag kliens &#8211;&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,75,49,6,13,4],"tags":[],"class_list":["post-1181","post","type-post","status-publish","format-standard","hentry","category-net","category-net-4","category-architektura","category-adatbazisok","category-design","category-szakmai-elet"],"_links":{"self":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1181"}],"version-history":[{"count":3,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1181\/revisions"}],"predecessor-version":[{"id":1183,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1181\/revisions\/1183"}],"wp:attachment":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}