{"id":1717,"date":"2014-09-18T09:08:38","date_gmt":"2014-09-18T07:08:38","guid":{"rendered":"http:\/\/soci.hu\/blog\/?p=1717"},"modified":"2014-09-18T09:08:38","modified_gmt":"2014-09-18T07:08:38","slug":"belassulo-webszerver-nyomozas","status":"publish","type":"post","link":"https:\/\/soci.hu\/blog\/index.php\/2014\/09\/18\/belassulo-webszerver-nyomozas\/","title":{"rendered":"Belassul\u00f3 webszerver nyomoz\u00e1s"},"content":{"rendered":"<p>Ny\u00e1ron k\u00e9t \u00e9rdekes \u00e9s neh\u00e9z esetem is volt \u00fcgyfelekn\u00e9l, mindkett\u0151h\u00f6z memory dumpokat is kellett elemezni WinDbg-gal. Elmes\u00e9lem az els\u0151t.<\/p>\n<p>Ebben teljesen kisz\u00e1m\u00edthatatlan m\u00f3don felment a webszerver cpu-ja 100%-ra, \u00e9s nagyon belassult a kiszolg\u00e1l\u00e1s raja. A procit a w3wp.exe vitte el, azaz nem valami meg\u0151r\u00fclt v\u00edrusirt\u00f3 vagy egy\u00e9b m\u00e1s \u00e1rtalmas processz. Sajnos az elej\u00e9n ez a t\u00e9ny, hogy nagy cpuval j\u00e1r egy\u00fctt a belassul\u00e1s nem volt m\u00e9g egy\u00e9rtelm\u0171, \u00edgy nem ebbe az ir\u00e1nyba kezd\u0151d\u00f6tt a nyomoz\u00e1s.<\/p>\n<p>DynaTrace agent fel volt telep\u00edtve a szerverekre (okos kis cucc), ami alapj\u00e1n l\u00e1tszottak a k\u00e9r\u00e9sekhez tartoz\u00f3 stack trace-ek \u00e9s .NET statisztik\u00e1k is. Az alapj\u00e1n vagy a webapp -> web service h\u00edv\u00e1sok voltak lass\u00faak, vagy a GC vitt el t\u00fal sok id\u0151t. A h\u00e1l\u00f3zati \u00e9s szerviz probl\u00e9m\u00e1t egy id\u0151 ut\u00e1n ki lehetett z\u00e1rni, mivel a szerviz oldalon p\u00e1r ms alatt lefutottak a h\u00edv\u00e1sok. A .NET h\u00e1l\u00f3zati traceinget is bekapcsoltuk, hogy webapp oldalr\u00f3l milyen id\u0151kkel mennek a h\u00edv\u00e1sok, de ebben minden inf\u00f3 benne volt, csak a timestampek nem. Nesze semmi fogd meg j\u00f3l.<\/p>\n<p>A GC \u00fcgyre nem tudtam semmit mondani. Eg\u00e9szen pontosan a DynaTrace Suspensi\u00f6nt mutatott, azaz valamire v\u00e1rakoztak a sz\u00e1lak. A doksija szerint ez \u00e1ltal\u00e1ban GC-re v\u00e1rakoz\u00e1st jelent. \u00c1ltal\u00e1ban. A .NET GC perfmon counterek ezt nem er\u0151s\u00edtett\u00e9k meg. A h\u00e1l\u00f3zatra \u00e9s egy\u00e9b IO-ra v\u00e1rakoz\u00e1s k\u00fcl\u00f6n t\u00e9tel volt a list\u00e1n, \u00edgy a suspension oka rejt\u00e9ly maradt. A memory dumpok nem seg\u00edtettek, mivel mind olyankor k\u00e9sz\u00fclt, amikor m\u00e1r rendben volt a g\u00e9p, apppol recycling miatt.<\/p>\n<p>Szerencs\u00e9re a tesztel\u0151 koll\u00e9ga nagyon lelkesen seg\u00edtkezett, \u00e9s a tesztjeivel siker\u00fclt reproduk\u00e1lni a probl\u00e9m\u00e1t. Hogy pontosabban l\u00e1ssuk, mi t\u00f6rt\u00e9nik, felraktunk egy g\u00e9pet a staging szerverre, \u00edgy \u00fagy tudtunk m\u00e9rni profilerrel, mi t\u00f6rt\u00e9nik a worker processzben.<\/p>\n<p>Amikor v\u00e9gre siker\u00fclt reproduk\u00e1lni a hib\u00e1t, v\u00e9gre saj\u00e1t szememmel l\u00e1ttam, hogy a cpuk ki\u00fclnek 100%-ra, \u00e9s odaragadnak. Annyira le volt terhelve a g\u00e9p, hogy nem is lehetett haszn\u00e1lni a profilert, task managerben el kellett vennem a processor affinity-n kereszt\u00fcl p\u00e1r procit a w3wpt\u0151l, hogy a visual studio egy\u00e1ltal\u00e1n meg tudjon nyekkenni.<\/p>\n<p>A profiler m\u00e1r k\u00f6zelebb vitt a probl\u00e9m\u00e1hoz, az id\u0151 z\u00f6me a <a href=\"http:\/\/referencesource.microsoft.com\/#mscorlib\/system\/collections\/generic\/dictionary.cs\">Dictionary<\/a>.FindEntry met\u00f3dus\u00e1ban ment el.<br \/>\nEzt h\u00edvja a TryGetValue, a ContainsKey \u00e9s az Indexer, ez a f\u0151 keres\u0151 r\u00e9sze. Mivel a Dictionary arr\u00f3l h\u00edres, hogy igen gyors, arra gondoltam csak az\u00e9rt megy el itt annyi id\u0151, mert v\u00e9gtelen cilusba ker\u00fcl a Dictionaryt h\u00edv\u00f3 k\u00f3d, valamilyen k\u00f3dszervez\u00e9si hiba miatt. Ez\u00e9rt raktunk a k\u00f3dba egy sz\u00e1ml\u00e1l\u00f3t, h\u00e1nyszor h\u00edvj\u00e1k meg a Dictionary-t piszk\u00e1l\u00f3 met\u00f3dust, \u00e9s kilogoltuk a % 1000000-dik h\u00edv\u00e1st. V\u00e1rtunk, v\u00e1rtunk, de nem keletkezett log.<\/p>\n<p>Ekkor n\u00e9mi gugliz\u00e1s ut\u00e1n tal\u00e1ltam r\u00e1 erre a <a href=\"http:\/\/blogs.msdn.com\/b\/tess\/archive\/2009\/12\/21\/high-cpu-in-net-app-using-a-static-generic-dictionary.aspx\">cikkre<\/a>. \u00c9s ekkor minden \u00f6ssze\u00e1llt. A Dictionary nem thread safe, csak olvas\u00e1sra. Ha t\u00f6bb sz\u00e1l egyszerre \u00edrja \u00e9s olvassa is, akkor beakadhat v\u00e9gtelen ciklusba a FindEntry met\u00f3dus!!!<\/p>\n<p>Ez itt k\u00e9rem a szop\u00f3roller:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nfor (int i = buckets&#x5B;hashCode % buckets.Length]; i &gt;= 0; i = entries&#x5B;i].next) \r\n{\r\n    if (entries&#x5B;i].hashCode == hashCode &amp;&amp; comparer.Equals(entries&#x5B;i].key, key)) return i;\r\n}\r\n<\/pre>\n<p>Ez a for soha nem \u00e9r v\u00e9get, extr\u00e9m ritka versenyhelyzet eset\u00e9n. Aljas, nem?<\/p>\n<p>Mi a megold\u00e1s? Meg kell \u00edrni a k\u00f3dot thread safe-re, lock-kal \u00e9s egyebekkel.<\/p>\n<p>A DynaTrace suspension id\u0151 ebb\u0151l k\u00f6vetkez\u0151en a thread cpura v\u00e1rakoz\u00e1st jelenette, annyira le volt fogva minden cpu, hogy az os k\u00e9nytelen volt elvenni magot a sz\u00e1lakt\u00f3l, ez l\u00e1tszott suspensionk\u00e9nt a riportokban. Tess\u00e9k b\u00e9k\u00e9n hagyni szeg\u00e9ny GC-t, mindig \u0151 a b\u0171nbak. :)<\/p>\n<p>Mit tenn\u00e9k m\u00e1sk\u00e9pp, hogy a k\u00f6vetkez\u0151 esetben c\u00e9lrat\u00f6r\u0151bben tal\u00e1ljam meg a probl\u00e9m\u00e1t?<\/p>\n<p>1. Sokkal szigor\u00fabban oda kell figyelni a makr\u00f3 adatok r\u00f6gz\u00edt\u00e9s\u00e9re. A performance counterek nagyon j\u00f3 h\u00e1tteret adnak, de ehhez t\u00e9nyleg napokig futtatni kell a perfmont, \u00e9s meg\u0151rizni a logokat a nyomoz\u00e1s v\u00e9g\u00e9ig.<\/p>\n<p>2. Semmit nem kell elhinni, mindent magunknak kell megn\u00e9zni. Pl., hogy a dump t\u00e9nyeg akkor k\u00e9sz\u00fclt-e, amikor m\u00e9g fenn\u00e1llt a hiba, m\u00e1sk\u00e9pp k\u00f6ny\u00e9kig turk\u00e1lhatunk a dumpban, nem lesz benne semmi \u00e9rdekes.<\/p>\n<p>3. Ha siker\u00fcl azonos\u00edtani a hiba indik\u00e1tor\u00e1t, pl. nagy cpu, lass\u00fa lapv\u00e9grhajt\u00e1s, exception\u00f6k, stb., akkor automatikus dumpokat kell k\u00e9sz\u00edteni, nem embereket zaklatni ezzel. A <a href=\"http:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=40336\">Debug Diagnostic Tool v2.0<\/a> erre van kital\u00e1lva. <\/p>\n<p>4. Nagy er\u0151fesz\u00edt\u00e9seket kell tenni, hogy rerpoduk\u00e1lni lehessen a  hib\u00e1t olyan k\u00f6rnyezetben, ahol van Visual Studio, \u00edgy debugger \u00e9s profofiler. A dump egy pillanatot kap el, mem\u00f3ria \u00e9s n\u00e9ha cpu elemz\u00e9sre is j\u00f3, de mivel csak egy pillanat l\u00e1tszik bel\u0151le, neh\u00e9z \u00f6sszerakni a nagy k\u00e9pet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ny\u00e1ron k\u00e9t \u00e9rdekes \u00e9s neh\u00e9z esetem is volt \u00fcgyfelekn\u00e9l, mindkett\u0151h\u00f6z memory dumpokat is kellett elemezni WinDbg-gal. Elmes\u00e9lem az els\u0151t. Ebben teljesen kisz\u00e1m\u00edthatatlan&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1717","post","type-post","status-publish","format-standard","hentry","category-szakmai-elet"],"_links":{"self":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1717","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=1717"}],"version-history":[{"count":2,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1717\/revisions"}],"predecessor-version":[{"id":1719,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1717\/revisions\/1719"}],"wp:attachment":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}