{"id":2032,"date":"2018-01-04T16:23:38","date_gmt":"2018-01-04T13:23:38","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=2032"},"modified":"2018-01-04T16:23:38","modified_gmt":"2018-01-04T13:23:38","slug":"resiliency-patterns-in-microservice-architecture","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/resiliency-patterns-in-microservice-architecture\/","title":{"rendered":"Microservice Mimarisinde Resiliency Pattern&#8217;lar\u0131"},"content":{"rendered":"<p>Merhaba arkada\u015flar.<\/p>\n<p>A\u00e7\u0131k\u00e7as\u0131 bir s\u00fcredir bu konu hakk\u0131nda bir makale yazmay\u0131 planl\u0131yordum. Ya\u015fam\u0131\u015f oldu\u011fum son blackfriday tecr\u00fcbesinden sonra, bu konu hakk\u0131nda bir \u015feyler yazman\u0131n s\u0131ras\u0131n\u0131n geldi\u011fini anlad\u0131m. Evet, konumuz microservice yap\u0131lar\u0131nda\u00a0<strong>resilience<\/strong> ve <strong>fault tolerance<\/strong>&#8216;\u0131n \u00f6nemi ve bunu nas\u0131l sa\u011flayabilece\u011fimiz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/12\/resilience-microservices.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2039 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/resilience-microservices.jpg\" alt=\"\" width=\"960\" height=\"320\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/resilience-microservices.jpg 960w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/resilience-microservices-300x100.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/resilience-microservices-768x256.jpg 768w\" data-sizes=\"(max-width: 960px) 100vw, 960px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 960px; --smush-placeholder-aspect-ratio: 960\/320;\" \/><\/a><\/p>\n<h4>Hikaye<\/h4>\n<p>Daha \u00f6nceki makalelerim i\u00e7erisinde, bir \u00e7ok kez microservice architecture&#8217;\u0131n\u0131n sisteme getirdi\u011fi avantajlardan hep bahsettim. Zaten bu makaleyi okuyorsan\u0131z e\u011fer, sizlerde microservice architecture&#8217;\u0131 \u00fczerinde olduk\u00e7a deneyim edinmi\u015fsinizdir. Ben son 3 y\u0131ld\u0131r microservice mimarileri \u00fczerinde yo\u011fun bir \u015fekilde \u00e7al\u0131\u015f\u0131yorum. Evet, o d\u00f6n\u00fc\u015f\u00fcm r\u00fczgar\u0131na ben de kendimi kapt\u0131rd\u0131m.<\/p>\n<p>Hayat, biliyoruz ki kusursuz diye bir \u015fey yok. (Yoksa var m\u0131?) Her g\u00fczel \u015fey bizim i\u00e7in yeni bir <strong>challenge<\/strong> meydana getiriyor. Do\u011fal olarak g\u00fczel olan her \u015feyin, beraberinde getirdi\u011fi bir tak\u0131m problemleri veya sorumluluklar\u0131 biliyor ve kabul ediyoruz. Tabi bazen \u00f6n g\u00f6remiyoruz.<\/p>\n<p>Her neyse, microservice architecture&#8217;\u0131 da asl\u0131nda benim i\u00e7in b\u00f6yle oldu. Distributed sistemlerin getirdi\u011fi baz\u0131 challenge&#8217;lar\u0131 kabul ettim\/ettik, baz\u0131lar\u0131n\u0131 da g\u00f6remedik. Evet, distributed olarak in\u015fa edilen microservice&#8217;ler, zaten do\u011fas\u0131 gere\u011fi meydana gelebilecek baz\u0131 hatalara kar\u015f\u0131 <strong>dayan\u0131kl\u0131d\u0131r<\/strong>. Monolith uygulamalara geriye d\u00f6n\u00fcp bir bakt\u0131\u011f\u0131m\u0131zda, herhangi bir hata meydana geldi\u011finde t\u00fcm uygulama ak\u0131\u015f\u0131n\u0131n olu\u015fan bu hatadan etkilendi\u011fini g\u00f6rmemek m\u00fcmk\u00fcn de\u011fil san\u0131r\u0131m.\u00a0Basit d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm\u00fczde bu hatalara \u00f6rnek olarak third-party API&#8217;lar\u0131n cevap vermemesi, network split&#8217;ler veya efektif olarak resource&#8217;lar\u0131n kullan\u0131lamamas\u0131ndan dolay\u0131 olu\u015fabilecek bottleneck&#8217;leri \u00f6rnek verebiliriz. Bu gibi sebeplerden dolay\u0131 uygulamalar\u0131 k\u00fc\u00e7\u00fck par\u00e7alardan olu\u015fturup, herhangi bir par\u00e7ada bir hata meydana geldi\u011finde, b\u00fct\u00fcn uygulama ak\u0131\u015f\u0131n\u0131n bu gibi hatalardan etkilenmemesini ve dayan\u0131kl\u0131 olmas\u0131n\u0131 sa\u011flamaya \u00e7al\u0131\u015f\u0131yoruz. \u00d6zellikle g\u00fcn\u00fcm\u00fcz teknoloji \u00e7a\u011f\u0131nda, para kayb\u0131 s\u00f6z konusu olunca b\u00fcy\u00fck de bir \u00f6nem ta\u015f\u0131yor.<\/p>\n<p>\u00d6zetle, microservice yakla\u015f\u0131m\u0131 ile b\u00fct\u00fcn sistem ak\u0131\u015f\u0131n\u0131n tek bir hata kar\u015f\u0131s\u0131nda tamamen etkilenmesini k\u0131smen de olsa \u00f6nlemi\u015f oluyoruz. (Tabi bu getirdi\u011fi avantajlardan sadece bir tanesi.) San\u0131r\u0131m buradaki as\u0131l soru ise, olu\u015fabilecek bu tarz hatalara kar\u015f\u0131 k\u00fc\u00e7\u00fck par\u00e7alardan olu\u015fan uygulamalar\u0131m\u0131z\u0131 daha fazla <b>dayan\u0131kl\u0131l\u0131k\u00a0<\/b>ve <b>esneklik\u00a0<\/b>g\u00f6sterebilmesi i\u00e7in, neler yapmal\u0131y\u0131z, sorusudur.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/12\/durability-sea.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2048 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/durability-sea.jpg\" alt=\"\" width=\"1000\" height=\"311\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/durability-sea.jpg 1000w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/durability-sea-300x93.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/durability-sea-768x239.jpg 768w\" data-sizes=\"(max-width: 1000px) 100vw, 1000px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1000px; --smush-placeholder-aspect-ratio: 1000\/311;\" \/><\/a><\/p>\n<p>Bu makale kapsam\u0131nda ise ya\u015fad\u0131\u011f\u0131m baz\u0131 tecr\u00fcbelerimden yola \u00e7\u0131kacak, uygulamalar\u0131m\u0131zda <strong>resilience<\/strong>&#8216;\u0131 (esneklik) sa\u011flayabilmek ad\u0131na\u00a0<strong>Circuit breaker<\/strong>, <strong>Retry mechanism<\/strong> ve <strong>Fallback<\/strong> i\u015flemleri gibi pattern ve implementasyonlardan bahsetmeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<h4>Circuit breaker&#8217;\u0131n \u00d6nemi<\/h4>\n<div>\n<div>Biliyoruz ki microservice d\u00fcnyas\u0131nda uygulamalar, bir \u00e7ok zaman birbirleri ile veya ba\u015fka bir remote service ile i\u015f birli\u011fi i\u00e7erisindedirler. Durum b\u00f6yle olunca network splits, timeouts veya uygulaman\u0131n a\u015f\u0131r\u0131 y\u00fcke maruz kalmas\u0131ndan dolay\u0131 ya\u015fanabilecek transient hatalar ile kar\u015f\u0131la\u015fmam\u0131z ka\u00e7\u0131n\u0131lmazd\u0131r. \u0130\u015fte bu noktada devreye circuit breaker girmektedir. Bir noktadan sonra tekrarlanan hatalara, bir dur! demek laz\u0131m de\u011fil mi?<\/div>\n<div><\/div>\n<div>Peki, nas\u0131l?<\/div>\n<div><a href=\"\/wp-content\/uploads\/2017\/12\/circuit_breaker_state_diagram.gif\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2052 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/circuit_breaker_state_diagram.gif\" alt=\"\" width=\"558\" height=\"301\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 558px; --smush-placeholder-aspect-ratio: 558\/301;\" \/><\/a><\/div>\n<\/div>\n<div>\n<div>Yukar\u0131daki diagrama bakarsak, temel olarak circuit breaker&#8217;\u0131n 3 temel mod&#8217;u vard\u0131r.<\/div>\n<\/div>\n<div><\/div>\n<div>\n<ul>\n<li><strong>Closed<\/strong>: Bu moddla circuit breaker kapal\u0131d\u0131r ve t\u00fcm request&#8217;ler ba\u015far\u0131yla ger\u00e7ekle\u015ftirilmektedir.<\/li>\n<li><strong>Open<\/strong>: Bu modda circuit breaker a\u00e7\u0131lm\u0131\u015ft\u0131r ve ba\u015far\u0131s\u0131z ger\u00e7ekle\u015fen request&#8217;leri, kendisine set edilen bir s\u00fcre kadar kesmi\u015ftir.<\/li>\n<li><strong>Half-Open<\/strong>: Bu modda ise circuit breaker hatan\u0131n hala devam edip etmedi\u011fini anlayabilmek ad\u0131na, bir ka\u00e7 request&#8217;in ger\u00e7ekle\u015fmesine izin vermektedir. E\u011fer hata sona erdi ise mod&#8217;unu closed, devam ediyor ise open durumuna alacakt\u0131r.<\/li>\n<\/ul>\n<p>Terminolojiyi bir kenara b\u0131rak\u0131rsak, en basit haliyle bir implementasyonunu yapal\u0131m.<\/p>\n<p>\u00d6ncelikle &#8220;<em>CircuitBreakerOptions<\/em><strong class=\"final-path\">&#8221;\u00a0<\/strong>isminde a\u015fa\u011f\u0131daki gibi bir class olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:default decode:true\">public class CircuitBreakerOptions\r\n{\r\n    public string Key { get; set; }\r\n    public int ExceptionThreshold {get; set;}\r\n    public int SuccessThresholdWhenCircuitBreakerHalfOpenStatus { get; set; }\r\n    public TimeSpan DurationOfBreak {get; set;}\r\n\r\n    public CircuitBreakerOptions(string key, int exceptionThreshold, int successThresholdWhenCircuitBreakerHalfOpenStatus, TimeSpan durationOfBreak)\r\n    {\r\n        Key = key;\r\n        ExceptionThreshold = exceptionThreshold;\r\n        SuccessThresholdWhenCircuitBreakerHalfOpenStatus = successThresholdWhenCircuitBreakerHalfOpenStatus;\r\n        DurationOfBreak = durationOfBreak;\r\n    }\r\n}<\/pre>\n<p>Bu class \u00fczerinden, circuit breaker&#8217;\u0131n devreye girebilmesi i\u00e7in i\u015flem bazl\u0131 olarak option&#8217;lar\u0131 alaca\u011f\u0131z. &#8220;<em>ExceptionThreshold<\/em>&#8221; property&#8217;si ile circuit breaker&#8217;\u0131n ne zaman devreye girmesi gerekti\u011fini, &#8220;<em>SuccessThresholdWhenCircuitBreakerHalfOpenStatus<\/em>&#8221; property&#8217;si ile de circuit breaker&#8217;\u0131n ne zaman kapanmas\u0131 gerekti\u011fini belirleyece\u011fiz. &#8220;<em>DurationOfBreak<\/em>&#8221; property&#8217;si ile ise, circuit breaker&#8217;\u0131n ne kadar bir s\u00fcre open mod&#8217;da kalaca\u011f\u0131n\u0131 belirleyece\u011fiz.<\/p>\n<p>Uygulaman\u0131n ya\u015fam\u0131 boyunca circuit breaker&#8217;\u0131n hangi anda devreye girece\u011fini, &#8220;<em>CircuitBreakerOptions<\/em>&#8221; class&#8217;\u0131 \u00fczerinden alaca\u011f\u0131m\u0131z baz\u0131 de\u011ferler ile belirleyece\u011fiz. Belirleyebilmek i\u00e7in ise uygulamada meydana gelebilecek olan hatalar\u0131, bir yerde store ediyor ve &#8220;<em>ExceptionThreshold<\/em>&#8221; de\u011ferini kontrol ediyor olmal\u0131y\u0131z.<\/p>\n<p>Bunun i\u00e7in, &#8220;<em>CircuitBreakerStateEnum<\/em>&#8221; ve &#8220;<em>CircuitBreakerStateModel<\/em>&#8221; class&#8217;\u0131n\u0131 a\u015fa\u011f\u0131daki gibi tan\u0131mlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true \">public enum CircuitBreakerStateEnum \r\n{\r\n    Open,\r\n    HalfOpen,\r\n    Closed\r\n}\r\n\r\npublic class CircuitBreakerStateModel\r\n{\r\n    public CircuitBreakerStateEnum State {get; set;}\r\n    public int ExceptionAttempt {get; set;}\r\n    public int SuccessAttempt {get; set;}\r\n    public Exception LastException {get; set;}\r\n    public DateTime LastStateChangedDateUtc {get; set;}\r\n    public bool IsClosed {get; set;}\r\n}<\/pre>\n<p>Enum i\u00e7erisinde circuit breaker&#8217;\u0131n sahip oldu\u011fu state&#8217;leri tan\u0131mlad\u0131k ve &#8220;<em>CircuitBreakerStateModel<\/em>&#8221; class&#8217;\u0131n\u0131 da, uygulama i\u00e7erisinde ger\u00e7ekle\u015fecek olan exception ve success gibi bilgileri tutmak i\u00e7in kullanaca\u011f\u0131z.<\/p>\n<p>\u015eimdi model&#8217;i store etmek i\u00e7in kullanaca\u011f\u0131m\u0131z k\u0131sm\u0131 kodlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public class CircuitBreakerStateStore\r\n{\r\n    private readonly ConcurrentDictionary&lt;string, CircuitBreakerStateModel&gt; _store = new ConcurrentDictionary&lt;string, CircuitBreakerStateModel&gt;();\r\n\r\n    public void ChangeLastStateChangedDateUtc(string key, DateTime date)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            stateModel.LastStateChangedDateUtc = date;\r\n            _store[key] = stateModel;\r\n        }\r\n    }\r\n\r\n    public void ChangeState(string key, CircuitBreakerStateEnum state)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            stateModel.State = state;\r\n            _store[key] = stateModel;\r\n        }\r\n    }\r\n\r\n    public int GetExceptionAttempt(string key)\r\n    {\r\n        int exceptionAttempt = 0;\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            exceptionAttempt = stateModel.ExceptionAttempt;\r\n        }\r\n\r\n        return exceptionAttempt;\r\n    }\r\n\r\n    public void IncreaseExceptionAttemp(string key)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            stateModel.ExceptionAttempt += 1;\r\n            _store[key] = stateModel;\r\n        }\r\n        else\r\n        {\r\n            stateModel = new CircuitBreakerStateModel();\r\n            stateModel.ExceptionAttempt += 1;\r\n\r\n            AddStateModel(key, stateModel);\r\n        }\r\n    }\r\n\r\n    public DateTime GetLastStateChangedDateUtc(string key)\r\n    {\r\n        DateTime lastStateChangedDateUtc = default(DateTime);\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            lastStateChangedDateUtc = stateModel.LastStateChangedDateUtc;\r\n        }\r\n\r\n        return lastStateChangedDateUtc;\r\n    }\r\n\r\n    public int GetSuccessAttempt(string key)\r\n    {\r\n        int successAttempt = 0;\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            successAttempt = stateModel.SuccessAttempt;\r\n        }\r\n\r\n        return successAttempt;\r\n    }\r\n\r\n    public void IncreaseSuccessAttemp(string key)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            stateModel.SuccessAttempt += 1;\r\n            _store[key] = stateModel;\r\n        }\r\n    }\r\n\r\n    public bool IsClosed(string key)\r\n    {\r\n        bool isClosed = true;\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            isClosed = stateModel.IsClosed;\r\n        }\r\n\r\n        return isClosed;\r\n    }\r\n\r\n    public void RemoveState(string key)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        _store.TryRemove(key, out stateModel);\r\n    }\r\n\r\n    public void SetLastException(string key, Exception ex)\r\n    {\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            stateModel.LastException = ex;\r\n            _store[key] = stateModel;\r\n        }\r\n    }\r\n\r\n    public Exception GetLastException(string key)\r\n    {\r\n        Exception lastException = null;\r\n        CircuitBreakerStateModel stateModel;\r\n        if (_store.TryGetValue(key, out stateModel))\r\n        {\r\n            lastException = stateModel.LastException;\r\n        }\r\n\r\n        return lastException;\r\n    }\r\n\r\n    public void AddStateModel(string key, CircuitBreakerStateModel circuitBreakerStateModel)\r\n    {\r\n        _store.TryAdd(key, circuitBreakerStateModel);\r\n    }\r\n}<\/pre>\n<p>&#8220;<em>CircuitBreakerStateStore<\/em>&#8221; class&#8217;\u0131 i\u00e7erisinde yapt\u0131\u011f\u0131m\u0131z tek olay, in-memory olarak function bazl\u0131 &#8220;<em>CircuitBreakerStateModel<\/em>&#8221; class&#8217;\u0131n\u0131 store etmek. Di\u011fer method&#8217;lar ise, function&#8217;a \u00f6zel state&#8217;in durumunu g\u00fcncellemek veya silmek i\u00e7in kullanaca\u011f\u0131m\u0131z method&#8217;lard\u0131r.<\/p>\n<p>Art\u0131k circuit breaker&#8217;\u0131 kodlama k\u0131sm\u0131na ge\u00e7ebiliriz. &#8220;<em>CircuitBreakerHelper<\/em>&#8221; isminde bir class olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi implementasyonu ger\u00e7ekle\u015ftirelim.<\/p>\n<pre class=\"lang:c# decode:true\">public class CircuitBreakerHelper\r\n{\r\n    private readonly CircuitBreakerOptions _circuitBreakerOptions;\r\n    private readonly CircuitBreakerStateStore _stateStore;\r\n    private readonly object _halfOpenSyncObject = new Object();\r\n\r\n    public CircuitBreakerHelper(CircuitBreakerOptions circuitBreakerOptions, CircuitBreakerStateStore stateStore)\r\n    {\r\n        _circuitBreakerOptions = circuitBreakerOptions;\r\n        _stateStore = stateStore;\r\n    }\r\n\r\n    public async Task&lt;T&gt; ExecuteAsync&lt;T&gt;(Func&lt;Task&lt;T&gt;&gt; func)\r\n    {\r\n        if (!IsClosed(_circuitBreakerOptions.Key))\r\n        {\r\n            if (_stateStore.GetLastStateChangedDateUtc(_circuitBreakerOptions.Key).Add(_circuitBreakerOptions.DurationOfBreak) &lt; DateTime.UtcNow)\r\n            {\r\n                bool lockTaken = false;\r\n                try\r\n                {\r\n                    Monitor.TryEnter(_halfOpenSyncObject, ref lockTaken);\r\n                    if (lockTaken)\r\n                    {\r\n                        HalfOpen(_circuitBreakerOptions.Key);\r\n\r\n                        var result = await func.Invoke();\r\n\r\n                        Reset(_circuitBreakerOptions.Key);\r\n\r\n                        return result;\r\n                    }\r\n                }\r\n                catch (Exception ex)\r\n                {\r\n                    Trip(_circuitBreakerOptions.Key, ex);\r\n                    throw;\r\n                }\r\n                finally\r\n                {\r\n                    if (lockTaken)\r\n                    {\r\n                        Monitor.Exit(_halfOpenSyncObject);\r\n                    }\r\n                }\r\n            }\r\n\r\n            throw new Exception(\"Circuit breaker timeout hasn't yet expired.\", _stateStore.GetLastException(_circuitBreakerOptions.Key));\r\n        }\r\n\r\n        try\r\n        {\r\n            var result = await func.Invoke();\r\n\r\n            return result;\r\n        }\r\n        catch (Exception ex)\r\n        {\r\n            Trip(_circuitBreakerOptions.Key, ex);\r\n            throw;\r\n        }\r\n    }\r\n\r\n    private bool IsClosed(string key)\r\n    {\r\n        return _stateStore.IsClosed(key);\r\n    }\r\n\r\n    private void HalfOpen(string key)\r\n    {\r\n        _stateStore.ChangeState(key, CircuitBreakerStateEnum.HalfOpen);\r\n        _stateStore.ChangeLastStateChangedDateUtc(key, DateTime.UtcNow);\r\n    }\r\n\r\n    private void Reset(string key)\r\n    {\r\n        _stateStore.IncreaseSuccessAttemp(key);\r\n\r\n        if (_stateStore.GetSuccessAttempt(key) &gt;= _circuitBreakerOptions.SuccessThresholdWhenCircuitBreakerHalfOpenStatus)\r\n        {\r\n            _stateStore.RemoveState(key);\r\n        }\r\n    }\r\n\r\n    private void Trip(string key, Exception ex)\r\n    {\r\n        _stateStore.IncreaseExceptionAttemp(key);\r\n\r\n        if (_stateStore.GetExceptionAttempt(key) &gt;= _circuitBreakerOptions.ExceptionThreshold)\r\n        {\r\n            _stateStore.SetLastException(key, ex);\r\n            _stateStore.ChangeState(key, CircuitBreakerStateEnum.Open);\r\n            _stateStore.ChangeLastStateChangedDateUtc(key, DateTime.UtcNow);\r\n        }\r\n    }\r\n}<\/pre>\n<p>B\u00fct\u00fcn hikaye &#8220;<em>ExecuteAsync<\/em>&#8221; method&#8217;u i\u00e7erisinde ger\u00e7ekle\u015fiyor. \u0130lk olarak circuit breaker state&#8217;inin ilgili function i\u00e7in open olup olmad\u0131\u011f\u0131na bak\u0131yoruz. E\u011fer open state&#8217;inde de\u011filse, a\u015fa\u011f\u0131daki try-catch blo\u011fu i\u00e7erisinde ilgili function&#8217;\u0131 invoke ediyoruz. Herhangi bir exception meydana gelirse, catch blo\u011funda yakalay\u0131p &#8220;<em>Trip<\/em>&#8221; method&#8217;u i\u00e7erisinde exception say\u0131s\u0131n\u0131 artt\u0131r\u0131yoruz ve threshold de\u011ferini kontrol ediyoruz. E\u011fer exception threshold de\u011feri a\u015f\u0131l\u0131rsa, circuit breaker&#8217;\u0131n state&#8217;ini open durumuna getirip a\u00e7\u0131ld\u0131\u011f\u0131 tarihi ise model \u00fczerinde g\u00fcncelliyoruz.<\/p>\n<p>\u0130kinci ak\u0131\u015f i\u00e7in tekrar &#8220;<em>ExecuteAsync&#8221; <\/em>method&#8217;una bakarsak, circuit breaker&#8217;\u0131n expire olma s\u00fcresini kontrol ediyoruz. Expire s\u00fcresi e\u011fer sona erdi ise circuit breaker&#8217;\u0131 direkt olarak kapatmak yerine, hatan\u0131n hala devam edip etmedi\u011fini anlayabilmek i\u00e7in bir lock olu\u015fturup, tek bir thread ile i\u015flemi tekrar deniyoruz. &#8220;<em>Reset<\/em>&#8221; method&#8217;u i\u00e7erisinde ise her bir ba\u015far\u0131l\u0131 i\u015flem say\u0131s\u0131n\u0131 kontrol ederek, circuit breaker&#8217;\u0131 kapat\u0131p kapatmayaca\u011f\u0131m\u0131za karar veriyoruz.<\/p>\n<p>Peki nas\u0131l kullanaca\u011f\u0131z?<\/p>\n<pre class=\"lang:c# decode:true\">var options = new CircuitBreakerOptions(key: \"CurrencyConverterSampleAPI\",\r\n                                        exceptionThreshold: 5,\r\n                                        successThresholdWhenCircuitBreakerHalfOpenStatus: 5,\r\n                                        durationOfBreak: TimeSpan.FromMinutes(5));\r\n\r\nCircuitBreakerHelper helper = new CircuitBreakerHelper(options, new CircuitBreakerStateStore());\r\n\r\nvar response = await helper.ExecuteAsync&lt;T&gt;(async () =&gt; {\r\n    \/\/ Some API call...\r\n});<\/pre>\n<p>Yukar\u0131daki gibi bir kullan\u0131mda circuit breaker, exception threshold de\u011feri &#8220;5&#8221; e ula\u015ft\u0131\u011f\u0131nda, &#8220;5&#8221; dakika boyunca i\u015flem ger\u00e7ekle\u015ftirmeyi durduracakt\u0131r. B\u00f6ylece hem sistem kaynaklar\u0131n\u0131n gereksiz yere kullan\u0131lmam\u0131\u015f olmas\u0131n\u0131, hem de baz\u0131 cascading failure&#8217;lar\u0131n \u00f6n\u00fcne de ge\u00e7ilmi\u015f olmas\u0131n\u0131 sa\u011flam\u0131\u015f olaca\u011f\u0131z.<\/p>\n<h4>Peki ya Retry M<strong>echanism<\/strong>?<\/h4>\n<p><a href=\"\/wp-content\/uploads\/2017\/12\/error-could-not-connect-to-the-game-server-please-try-6778811.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2065 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/error-could-not-connect-to-the-game-server-please-try-6778811.png\" alt=\"\" width=\"500\" height=\"397\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/error-could-not-connect-to-the-game-server-please-try-6778811.png 500w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/error-could-not-connect-to-the-game-server-please-try-6778811-300x238.png 300w\" data-sizes=\"(max-width: 500px) 100vw, 500px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 500px; --smush-placeholder-aspect-ratio: 500\/397;\" \/><\/a><\/p>\n<p>\u00d6zellikle remote resource&#8217;lar ile \u00e7al\u0131\u015f\u0131yorsak, retry i\u015flemleri olmazsa olmazlardand\u0131r galiba. Bir \u00e7ok durum kar\u015f\u0131s\u0131nda ba\u015far\u0131s\u0131z ger\u00e7ekle\u015fen i\u015flemler, 2. veya 3. denemelerde genellikle ba\u015far\u0131yla ger\u00e7ekle\u015fmektedirler.<\/p>\n<p>Retry i\u015flemleri \u00f6zellikle distributed sistemler i\u00e7erisinde,\u00a0<strong>transient<\/strong> hatalara kar\u015f\u0131 kullanabilece\u011fimiz en iyi se\u00e7eneklerden birisidir.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/12\/retry-policy.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2073 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/retry-policy.png\" alt=\"\" width=\"538\" height=\"216\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/retry-policy.png 538w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/retry-policy-300x120.png 300w\" data-sizes=\"(max-width: 538px) 100vw, 538px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 538px; --smush-placeholder-aspect-ratio: 538\/216;\" \/><\/a><\/p>\n<p>Peki bunu nas\u0131l implemente edebiliriz?<\/p>\n<p>&#8220;<em>RetryMechanismOptions<\/em><strong class=\"final-path\">&#8221;\u00a0<\/strong>isminde a\u015fa\u011f\u0131daki gibi bir class olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public class RetryMechanismOptions\r\n{\r\n    public RetryPolicies RetryPolicies { get; set; }\r\n    public int RetryCount { get; set; }\r\n    public TimeSpan Interval { get; set; }\r\n\r\n    public RetryMechanismOptions(RetryPolicies retryPolicies, int retryCount, TimeSpan interval)\r\n    {\r\n        RetryPolicies = retryPolicies;\r\n        RetryCount = retryCount;\r\n        Interval = interval;\r\n    }\r\n}\r\n\r\npublic enum RetryPolicies\r\n{\r\n    Linear\r\n}<\/pre>\n<p>Bu class ile, retry i\u015flemlerinde kullanabilmek i\u00e7in bir tak\u0131m parametreleri alaca\u011f\u0131z. &#8220;<em>RetryPolicies<\/em>&#8221; enum&#8217;\u0131 ile back-off senaryolar\u0131n\u0131 belirleyece\u011fiz. Bu implementasyon i\u00e7erisinde sadece &#8220;<em>Linear<\/em>&#8221; olarak implemente edece\u011fiz. &#8220;<em>RetryCount<\/em>&#8221; ile ise ka\u00e7 kere retry i\u015flemi ger\u00e7ekle\u015ftirece\u011fimizi belirleyece\u011fiz.<\/p>\n<p>\u015eimdi &#8220;<em>RetryMechanismBase<\/em>&#8221; isminde bir abstract class olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public abstract class RetryMechanismBase\r\n{\r\n    private readonly RetryMechanismOptions _retryMechanismOptions;\r\n\r\n    public RetryMechanismBase(RetryMechanismOptions retryMechanismOptions)\r\n    {\r\n        _retryMechanismOptions = retryMechanismOptions;\r\n    }\r\n\r\n    public async Task&lt;T&gt; ExecuteAsync&lt;T&gt;(Func&lt;Task&lt;T&gt;&gt; func)\r\n    {\r\n        int currentRetryCount = 0;\r\n\r\n        for(;;)\r\n        {\r\n            try\r\n            {\r\n                return await func.Invoke();\r\n            }\r\n            catch(Exception ex)\r\n            {\r\n                currentRetryCount++;\r\n\r\n                bool isTransient = await IsTransient(ex);\r\n                if(currentRetryCount &gt; _retryMechanismOptions.RetryCount || !isTransient)\r\n                {\r\n                    throw;\r\n                }\r\n            }\r\n\r\n            await HandleBackOff();\r\n        }\r\n    }\r\n\r\n    protected abstract Task HandleBackOff();\r\n    \r\n    private Task&lt;bool&gt; IsTransient(Exception ex)\r\n    {\r\n        bool isTransient = false;\r\n        var webException = ex as WebException;\r\n\r\n        if(webException != null)\r\n        {\r\n            isTransient = new[] {WebExceptionStatus.ConnectionClosed,\r\n                            WebExceptionStatus.Timeout,\r\n                            WebExceptionStatus.RequestCanceled,\r\n                            WebExceptionStatus.KeepAliveFailure,\r\n                            WebExceptionStatus.PipelineFailure,\r\n                            WebExceptionStatus.ReceiveFailure,\r\n                            WebExceptionStatus.ConnectFailure,\r\n                            WebExceptionStatus.SendFailure}\r\n                            .Contains(webException.Status);\r\n        }\r\n\r\n        return Task.FromResult(isTransient);\r\n    }\r\n}<\/pre>\n<p>&#8220;<em>ExecuteAsync<\/em>&#8221; method&#8217;u i\u00e7erisinde, &#8220;<em>RetryMechanismOptions<\/em>&#8221; class&#8217;\u0131 i\u00e7erisinden ald\u0131\u011f\u0131m\u0131z parametreler do\u011frultusunda, retry i\u015flemini ger\u00e7ekle\u015ftirece\u011fiz. Back-off&#8217;lar\u0131, concrete class&#8217;lar i\u00e7erisinden handle edece\u011fiz. &#8220;<em>IsTransient<\/em>&#8221; method&#8217;u ile ise, uygulama i\u00e7erisinde meydana gelebilecek olan exception&#8217;\u0131n transient olup olmad\u0131\u011f\u0131na karar verece\u011fiz.<\/p>\n<blockquote><p><strong>NOT<\/strong>: &#8220;<em>IsTransient<\/em>&#8221; method&#8217;u i\u00e7erisinde, kullan\u0131c\u0131n\u0131n transient exception tip&#8217;lerini inject edebilmesini sa\u011flayabilirsiniz.<\/p><\/blockquote>\n<p>Art\u0131k bir retry strategy&#8217;si implemente edebiliriz. &#8220;<em>RetryLinearMechanismStrategy<\/em>&#8221; isminde bir class olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi kodlayal\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public class RetryLinearMechanismStrategy : RetryMechanismBase\r\n{\r\n    private readonly RetryMechanismOptions _retryMechanismOptions;\r\n\r\n    public RetryLinearMechanismStrategy(RetryMechanismOptions retryMechanismOptions)\r\n        :base(retryMechanismOptions)\r\n    {\r\n        _retryMechanismOptions = retryMechanismOptions;\r\n    }\r\n\r\n    protected override async Task HandleBackOff()\r\n    {\r\n        await Task.Delay(_retryMechanismOptions.Interval);\r\n    }\r\n}<\/pre>\n<p>Burada &#8220;<em>HandleBackOff<\/em>&#8221; method&#8217;unu override ederek, &#8220;<em>RetryMechanismOptions<\/em>&#8221; i\u00e7erisinde belirlenen &#8220;<em>Interval<\/em>&#8221; de\u011feri kadar task&#8217;\u0131, delay ettik.<\/p>\n<p>\u015eimdi retry i\u015flemlerini basit\u00e7e kullanabilmek i\u00e7in bir wrapper class&#8217;a ihtiyac\u0131m\u0131z var. Bunun i\u00e7in &#8220;<em>RetryHelper<\/em>&#8221; isminde a\u015fa\u011f\u0131daki gibi bir class olu\u015ftural\u0131m.<\/p>\n<pre class=\"lang:c# decode:true\">public class RetryHelper\r\n{\r\n    public async Task&lt;T&gt; Retry&lt;T&gt;(Func&lt;Task&lt;T&gt;&gt; func, RetryMechanismOptions retryMechanismOptions)\r\n    {\r\n        RetryMechanismBase retryMechanism = null;\r\n\r\n        if(retryMechanismOptions.RetryPolicies == RetryPolicies.Linear)\r\n        {\r\n            retryMechanism = new RetryLinearMechanismStrategy(retryMechanismOptions);\r\n        }\r\n\r\n        return await retryMechanism.ExecuteAsync(func);\r\n    }\r\n}<\/pre>\n<p>Retry implementasyonu bu kadar. Peki bunu nas\u0131l kullanaca\u011f\u0131z?<\/p>\n<pre class=\"lang:c# decode:true\">RetryHelper retryHelper = new RetryHelper();\r\n\r\nvar response = await helper.Retry&lt;T&gt;(async () =&gt; {\r\n    \/\/ Some API call...\r\n}, new RetryMechanismOptions(retryPolicies: RetryPolicies.Linear,\r\n                             retryCount: 3,\r\n                             interval: TimeSpan.FromSeconds(5)));<\/pre>\n<p>Yukar\u0131daki gibi bir kullan\u0131mda, uygulama i\u00e7erisinde web kaynakl\u0131 bir transient hata meydana gelirse, i\u015flem 5&#8217;er saniye ara ile 3 kez tekrar denenecektir. Bu sayede e\u011fer transient bir hata ile kar\u015f\u0131la\u015f\u0131l\u0131rsa, ilgili request kaybedilmemi\u015f olacakt\u0131r.<\/p>\n<h4>Peki i\u015fler planland\u0131\u011f\u0131 gibi gitmezse? Fallbacks!<\/h4>\n<p>Fallback i\u00e7in k\u0131saca bir <strong>backup<\/strong> stratejisi diyebiliriz san\u0131r\u0131m. E\u011fer bir microservice architecture&#8217;\u0131 tasarl\u0131yorsak, fallback stratejileri ger\u00e7ekten b\u00fcy\u00fck bir \u00f6nem ta\u015f\u0131maktad\u0131r.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2017\/12\/fallback.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2081 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/fallback.jpg\" alt=\"\" width=\"816\" height=\"397\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fallback.jpg 816w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fallback-300x146.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fallback-768x374.jpg 768w\" data-sizes=\"(max-width: 816px) 100vw, 816px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 816px; --smush-placeholder-aspect-ratio: 816\/397;\" \/><\/a><\/p>\n<p>\u00d6rne\u011fin, bir e-commerce web-sitesi \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z\u0131 d\u00fc\u015f\u00fcnelim. Bir sipari\u015f olu\u015ftu\u011funda, \u00f6deme i\u015flemini X bankas\u0131n\u0131n\u00a0<em>API<\/em>&#8216;\u0131 \u00fczerinden ger\u00e7ekle\u015ftiriyoruz. Fakat \u00f6deme i\u015flemi s\u0131ras\u0131nda, X bankas\u0131n\u0131n <em>API<\/em>&#8216;\u0131 \u00fczerinden beklenmedik bir \u015fekilde \u00f6deme i\u015flemini ger\u00e7ekle\u015ftiremedik. Peki, \u015fimdi ne olacak? Evet, retry i\u015flemlerini de ger\u00e7ekle\u015ftirdi\u011fimizi varsayal\u0131m ve hala \u00f6deme i\u015flemini tamamlayam\u0131yoruz. \u0130\u015fte buna benzer durumlarda, belirleyece\u011fimiz bir fallback stratejisi b\u00fcy\u00fck bir \u00f6nem ta\u015f\u0131maktad\u0131r. Yani X bankas\u0131 <em>API<\/em>&#8216;\u0131 yerine, B bankas\u0131n\u0131n <em>API<\/em>&#8216;\u0131 \u00fczerinden \u00f6deme i\u015flemini ger\u00e7ekle\u015ftirebilmek gibi.<\/p>\n<p>\u00d6zetle, kulland\u0131\u011f\u0131m\u0131z service&#8217;ler, unavailable oldu\u011funda ne yapaca\u011f\u0131m\u0131za karar vermek. Circuit breaker, retry mechanism ve fallback&#8217;den bahsettik. Peki basit bir \u00f6rnek olarak, fallback ile beraber bu pattern&#8217;lar\u0131 nas\u0131l kullanabiliriz?<\/p>\n<pre class=\"lang:c# decode:true\">public async Task&lt;T&gt; ExecuteAsync&lt;T&gt;(Func&lt;Task&lt;T&gt;&gt; func, string funcKey, Func&lt;Task&lt;T&gt;&gt; fallbackFunc = null)\r\n{\r\n    try\r\n    {\r\n        \/\/ Some checks... If retry mechanism uses...blablabla\r\n        RetryHelper helper = new RetryHelper();\r\n\r\n        return await helper.Retry&lt;T&gt;(func, new RetryMechanismOptions(retryPolicies: RetryPolicies.Linear,\r\n                                     retryCount: 3,\r\n                                     interval: TimeSpan.FromSeconds(5)));\r\n    }\r\n    catch\r\n    {\r\n        \/\/ Some checks... If circuit breaker uses...blablabla\r\n\r\n        try\r\n        {\r\n            var options = new CircuitBreakerOptions(key: funcKey,\r\n                                exceptionThreshold: 5,\r\n                                successThresholdWhenCircuitBreakerHalfOpenStatus: 5,\r\n                                durationOfBreak: TimeSpan.FromMinutes(5));\r\n\r\n            CircuitBreakerHelper helper = new CircuitBreakerHelper(options, new CircuitBreakerStateStore());\r\n\r\n            return await helper.ExecuteAsync(func);\r\n        }\r\n        catch (Exception)\r\n        {\r\n            if (fallbackFunc != null)\r\n            {\r\n                var result = await fallbackFunc.Invoke();\r\n\r\n                return result;\r\n            }\r\n\r\n            throw;\r\n        }\r\n    }\r\n}<\/pre>\n<p>Yukar\u0131daki method i\u00e7erisinde, \u00f6nce retry i\u015flemlerini deniyoruz. E\u011fer bir problem ile kar\u015f\u0131la\u015f\u0131rsak, circuit breaker&#8217;a g\u00f6nderiyoruz. Circuit breaker i\u00e7erisinden de unexcepted bir durum olu\u015fursa ve fallback&#8217;e sahipsek, fallback&#8217;i devreye sokuyoruz.<\/p>\n<p>Daha g\u00f6rsel olabilmesi a\u00e7\u0131s\u0131ndan, a\u015fa\u011f\u0131daki gibi basit bir sequence diagram\u0131 \u00e7izmeye \u00e7al\u0131\u015ft\u0131m.<a href=\"\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices.jpeg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-2078 lazyload\" data-src=\"\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices.jpeg\" alt=\"\" width=\"1760\" height=\"1060\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices.jpeg 1760w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices-300x181.jpeg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices-768x463.jpeg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/fault-tolerance-in-microservices-1024x617.jpeg 1024w\" data-sizes=\"(max-width: 1760px) 100vw, 1760px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1760px; --smush-placeholder-aspect-ratio: 1760\/1060;\" \/><\/a><\/p>\n<p>Makalenin ba\u015f\u0131nda da bahsetti\u011fim gibi, uzun zamand\u0131r bu makaleyi yazmay\u0131 hep d\u00fc\u015f\u00fcn\u00fcyordum. Sonunda tamamlayabildim. Umar\u0131m, akl\u0131mdakileri do\u011fru bir \u015fekilde sizlere aktarabilmi\u015fimdir.<\/p>\n<p>Microservice architecture&#8217;\u0131 design ederken, uygulamalar\u0131m\u0131z\u0131n <strong>resilience<\/strong>&#8216;a ve <strong>fault-tolerance<\/strong>&#8216;a sahip olmalar\u0131n\u0131n \u00f6neminden ve nas\u0131l implemente edebiliriz konular\u0131ndan bahsetmeye \u00e7al\u0131\u015ft\u0131m. Tabi bunlar sadece bir k\u0131sm\u0131.<\/p>\n<p>Son s\u00f6z olarak uygulamalar\u0131 nas\u0131l tasarlad\u0131\u011f\u0131m\u0131zla beraber, bir hata kar\u015f\u0131s\u0131nda veya unexcepted durumlarda nas\u0131l davranmas\u0131 gerekti\u011fini bilmesi de, b\u00fcy\u00fck bir \u00f6nem ta\u015f\u0131maktad\u0131r.<\/p>\n<p>\u00d6rnek proje:\u00a0<a href=\"https:\/\/github.com\/GokGokalp\/Luffy\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/GokGokalp\/Luffy<\/a><\/p>\n<h5>Referanslar<\/h5>\n<blockquote><p>https:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/retry<br \/>\nhttps:\/\/docs.microsoft.com\/en-us\/azure\/architecture\/patterns\/circuit-breaker<\/p><\/blockquote>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Merhaba arkada\u015flar. A\u00e7\u0131k\u00e7as\u0131 bir s\u00fcredir bu konu hakk\u0131nda bir makale yazmay\u0131 planl\u0131yordum. Ya\u015fam\u0131\u015f oldu\u011fum son blackfriday tecr\u00fcbesinden sonra, bu konu hakk\u0131nda bir \u015feyler yazman\u0131n s\u0131ras\u0131n\u0131n geldi\u011fini anlad\u0131m. Evet, konumuz microservice yap\u0131lar\u0131nda\u00a0resilience ve fault tolerance&#8216;\u0131n \u00f6nemi ve bunu nas\u0131l sa\u011flayabilece\u011fimiz. Hikaye Daha \u00f6nceki makalelerim i\u00e7erisinde, bir&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/resiliency-patterns-in-microservice-architecture\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">Microservice Mimarisinde Resiliency Pattern&#8217;lar\u0131<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":2033,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,68,368],"tags":[479,475,410,474,472,259,476,477,478,471,473],"class_list":["post-2032","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-architectural","category-microservices","tag-asp-net-core-microservice","tag-backoff","tag-circuit-breaker","tag-fallback","tag-fault-tolerance","tag-microservice","tag-microservice-circuit-breaker","tag-microservice-fault-tolerance","tag-microservice-resilience","tag-resilience","tag-retry-mechanism","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Microservice Mimarisinde Resiliency Pattern&#039;lar\u0131 - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Microservice Mimarisinde Resiliency Pattern&#039;lar\u0131 - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2018-01-04T13:23:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"680\" \/>\n\t<meta property=\"og:image:height\" content=\"450\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"26 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"Microservice Mimarisinde Resiliency Pattern&#8217;lar\u0131\",\"datePublished\":\"2018-01-04T13:23:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/\"},\"wordCount\":3500,\"commentCount\":10,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/microservices-resilience.jpg\",\"keywords\":[\"asp.net core microservice\",\"backoff\",\"circuit breaker\",\"fallback\",\"fault tolerance\",\"MicroService\",\"microservice circuit breaker\",\"microservice fault tolerance\",\"microservice resilience\",\"resilience\",\"retry mechanism\"],\"articleSection\":[\".NET\",\"Architectural\",\"Microservices\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/\",\"name\":\"Microservice Mimarisinde Resiliency Pattern'lar\u0131 - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/microservices-resilience.jpg\",\"datePublished\":\"2018-01-04T13:23:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/microservices-resilience.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2017\\\/12\\\/microservices-resilience.jpg\",\"width\":680,\"height\":450},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/resiliency-patterns-in-microservice-architecture\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Resiliency Patterns in Microservice Architecture\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Microservice Mimarisinde Resiliency Pattern'lar\u0131 - G\u00f6khan G\u00f6kalp","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:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/","og_locale":"tr_TR","og_type":"article","og_title":"Microservice Mimarisinde Resiliency Pattern'lar\u0131 - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2018-01-04T13:23:38+00:00","og_image":[{"width":680,"height":450,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"26 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"Microservice Mimarisinde Resiliency Pattern&#8217;lar\u0131","datePublished":"2018-01-04T13:23:38+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/"},"wordCount":3500,"commentCount":10,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg","keywords":["asp.net core microservice","backoff","circuit breaker","fallback","fault tolerance","MicroService","microservice circuit breaker","microservice fault tolerance","microservice resilience","resilience","retry mechanism"],"articleSection":[".NET","Architectural","Microservices"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/","url":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/","name":"Microservice Mimarisinde Resiliency Pattern'lar\u0131 - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg","datePublished":"2018-01-04T13:23:38+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2017\/12\/microservices-resilience.jpg","width":680,"height":450},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/resiliency-patterns-in-microservice-architecture\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Resiliency Patterns in Microservice Architecture"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2032","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=2032"}],"version-history":[{"count":63,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2032\/revisions"}],"predecessor-version":[{"id":2112,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/2032\/revisions\/2112"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/2033"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=2032"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=2032"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=2032"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}