{"id":33196,"date":"2021-06-22T18:30:00","date_gmt":"2021-06-22T16:30:00","guid":{"rendered":"https:\/\/blexin.com\/?p=33196"},"modified":"2021-07-09T17:03:39","modified_gmt":"2021-07-09T15:03:39","slug":"rendere-i-sistemi-resilienti-con-polly","status":"publish","type":"post","link":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/","title":{"rendered":"Rendere i sistemi resilienti con Polly"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"33197\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/attachment\/11_ita_1105x656_blog-polly\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&amp;ssl=1\" data-orig-size=\"1105,656\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"11_ITA_1105x656_blog-polly\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-33197\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly-1024x608.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Chi non ha mai sentito il termine \u201cresilienza\u201d? In questo periodo di pandemia, forse, si \u00e8 sentito ancora di pi\u00f9, tanto che \u00e8 stato associato ai piani dei vari paesi per ripartire dopo questo periodo buio.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ma cosa intendiamo per resilienza? La scienza indica con questa parola la capacit\u00e0 di un materiale di resistere alla rottura in seguito ad una sollecitazione dinamica e per alcuni materiali la capacit\u00e0 di riprendere, dopo una deformazione, l\u2019aspetto originale.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Non vi sorprender\u00e0, allora, che questo termine sia utilizzato anche in ambito software.&nbsp;&nbsp;L\u2019<em>INCOSE<\/em> (International Council on Systems Engineering), che si occupa di promuovere l\u2019ingegneria dei sistemi attraverso conferenze, gruppi di lavoro e pubblicazioni, fornisce questa <a href=\"https:\/\/www.incose.org\/incose-member-resources\/working-groups\/analytic\/resilient-systems\" target=\"_blank\" rel=\"noreferrer noopener\">definizione<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>La Resilienza \u00e8 l\u2019abilit\u00e0 di fornire le risposte necessarie nell\u2019affrontare le avversit\u00e0 (evitando, resistendo, recuperando, evolvendo e adattandosi)<\/em><\/p><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Nelle applicazioni cloud a microservizi o, in generale, in quelle distribuite, in cui \u00e8 presente una continua comunicazione tra servizi o risorse esterne, sono molto frequenti errori temporanei o transienti. Si tratta di errori dovuti a perdita di connessione o indisponibilit\u00e0 temporanea di un servizio. La natura di questo tipo di errori implica che un successivo tentativo di richiesta o operazione possa andare a buon fine.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uno dei modi per rendere resilienti e robusti e quindi stabili questi sistemi \u00e8 ricorrere al RETRY Pattern. Questo pattern consiste semplicemente nel ripetere un\u2019operazione a seguito di un fallimento.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le strategie da applicare secondo questo pattern sono diverse e dipendono dalla tipologia di errore riscontrato:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>Cancel <\/em>\u2013 Errore non transiente, sarebbe inutile riprovare l\u2019operazione fallita. Bisogna fermare l\u2019operazione e notificare l\u2019errore mediante eccezione o magari gestirlo.&nbsp;&nbsp;<\/li><li><em>Retry <\/em>\u2013 Errore raro o inusuale. \u00c8 molto probabile che ripetendo l\u2019operazione essa abbia esito positivo&nbsp;<\/li><li><em>Retry after delay<\/em> \u2013 Errore noto dovuto a problemi di connessione o occupazione di un servizio. Potrebbe essere necessario ritardare la ripetizione dell\u2019operazione prima di riprovare.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Lavorando su un sistema di un nostro cliente, in cui pi\u00f9 servizi comunicano tra loro tramite messaggi scambiati mediante RabbitMQ, \u00e8 capitato pi\u00f9 volte di dover fare interventi sul meccanismo di retry strategy presente sui loro software. Questo meccanismo era stato implementato internamente al team e non era facilmente mantenibile. Cos\u00ec insieme al team si \u00e8 deciso di fare un bel refactoring al codice e di introdurre una libreria gi\u00e0 esistente, nata proprio con lo scopo di aiutare gli sviluppatori nella gestione degli errori e rendere le applicazioni resilienti attraverso diverse policy di gestione. Questa libreria si chiama <em><a href=\"https:\/\/github.com\/App-vNext\/Polly\" target=\"_blank\" rel=\"noreferrer noopener\">P<\/a><\/em><a href=\"https:\/\/github.com\/App-vNext\/Polly\" target=\"_blank\" rel=\"noreferrer noopener\"><em>olly<\/em><\/a> ed \u00e8 riconosciuta ufficialmente da Microsoft.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"128\" height=\"128\" data-attachment-id=\"33203\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/attachment\/image_1-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_1.png?fit=128%2C128&amp;ssl=1\" data-orig-size=\"128,128\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image_1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_1.png?fit=128%2C128&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_1.png?resize=128%2C128&#038;ssl=1\" alt=\"Polly logo\" class=\"wp-image-33203\"\/><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Polly offre diverse <em>policy <\/em>di resilienza che potete trovare <a href=\"https:\/\/github.com\/App-vNext\/Polly#resilience-policies%22%20HYPERLINK%20%22https:\/\/github.com\/App-vNext\/Polly#resilience-policies\" target=\"_blank\" rel=\"noreferrer noopener\">qui<\/a> ma oggi ci soffermeremo su quella di <em>Retry<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"834\" height=\"736\" data-attachment-id=\"33205\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/attachment\/image_2-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_2.png?fit=834%2C736&amp;ssl=1\" data-orig-size=\"834,736\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image_2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_2.png?fit=834%2C736&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_2.png?resize=834%2C736&#038;ssl=1\" alt=\"diagram policy polly\" class=\"wp-image-33205\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/image_2.png 834w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/image_2-480x424.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 834px, 100vw\" \/><figcaption>Fonte:<a href=\"https:\/\/github.com\/App-vNext\/Polly\/wiki\/Retry#how-polly-retry-works\" target=\"_blank\" rel=\"noreferrer noopener\"> https:\/\/github.com\/App-vNext\/Polly\/wiki\/Retry#how-polly-retry-works<\/a><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Per mostrare meglio il funzionamento di Polly pu\u00f2 essere utile un esempio. Prendiamo il codice da uno dei <a href=\"https:\/\/blexin.com\/it\/blog\/disaccoppiare-la-comunicazione-con-rabbitmq\/\" target=\"_blank\" rel=\"noreferrer noopener\">primi articoli su RabbitMQ<\/a> che abbiamo pubblicato sul nostro blog.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In particolare, prendiamo il codice del Sender ovvero un software che invia messaggi tramite un Broker di messaggi RabbitMQ.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per simulare un errore transiente andremo a stoppare il container su cui viene eseguito il broker RabbitMQ e lo riavvieremo subito dopo.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Partiamo dal codice di base a cui ho apportato alcune modifiche. A scopo illustrativo ho creato un array di stringhe, ovvero i messaggi che invieremo, riempito tramite il metodo FillMessages(), inoltre ho estratto in un metodo la parte di codice che va a sfruttare il driver di RabbitMQ per la pubblicazione dei messaggi. Per evitare la perdita di messaggi in caso di stop temporaneo del broker, andremo a settare la coda dichiarata come <strong>durable <\/strong>e andremo a specificare che i messaggi pubblicati saranno di tipo <strong>persistent<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nnamespace Sender \n{ \n        class Sender \n        { \n        public static void Main() \n        { \n        var factory = new ConnectionFactory() { HostName = &quot;localhost&quot; }; \n        using (var connection = factory.CreateConnection()) \n        using (var channel = connection.CreateModel()) \n        { \n                channel.QueueDeclare(queue: &quot;QueueDemo&quot;, \n                                     durable: true, \n                                     exclusive: false, \n                                     autoDelete: false, \n                                     arguments: null); \n  \n                var messages = new string &#x5B;100]; \n                FillMessages(messages); \n                foreach (var message in messages) \n                       { \n                        PublishMessage(message, channel); \n                       Thread.Sleep(2000); \n                       } \n        } \n\n        Console.WriteLine(&quot; Press &#x5B;enter] to exit.&quot;); \n        Console.ReadLine(); \n        } \n \n    \tprivate static void FillMessages(string&#x5B;] arrayToFill) \n    \t{ \n        for (var j = 0; j &lt; arrayToFill.Length; j++) \n        { \n                arrayToFill&#x5B;j] = $&quot;Message {j}&quot;; \n        } \n    \t} \n \n    \tprivate static void PublishMessage(string message, IModel channel) \n    \t{ \n        var body = Encoding.UTF8.GetBytes(message); \n        channel.BasicPublish(exchange: &quot;&quot;, \n                routingKey: &quot;QueueDemo&quot;, \n                basicProperties: new BasicProperties{DeliveryMode = 2}, \n            \tbody: body); \n        Console.WriteLine($&quot;Sent {message}&quot;); \n        } \n        } \n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Per utilizzare <em>Polly<\/em> in una nostra applicazione ci sono degli step da seguire.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 1) Specificare l\u2019eccezione\/i che la policy deve gestire<\/strong>&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se lanciassimo il Sender e, durante l\u2019invio dei messaggi, stoppassimo il container sui cui \u00e8 eseguito RabbitMQ riceveremmo questo tipo di eccezione:&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Unhandled Exception: RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted<\/em>&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Definiamo allora una policy per gestire questa eccezione mediante il metodo <em>Handle<\/em>().&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nvar retryPolicy = Policy.Handle&amp;lt; AlreadyClosedException &gt;(); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 2) Specificare come la policy deve gestire l\u2019errore<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supponiamo, quindi, che la perdita di connessione al broker sia un problema noto o comunque un errore transiente che per quanto detto in procedenza \u00e8 gestibile con una strategia di<strong> <\/strong>Retry. Ci sono diversi modi per definire con Polly il modo con cui si vuole riprovare una determinata operazione. Il metodo pi\u00f9 semplice \u00e8 il metodo <em>Retry<\/em>() al quale eventualmente possiamo passare un parametro di tipo intero per indicare il numero di volte che si vuole ripetere l\u2019operazione.&nbsp;Oppure possiamo riprovare per sempre mediante il metodo <em>RetryForever<\/em>().<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Come abbiamo detto in precedenza, quando siamo al cospetto di errori comuni di connessione, un\u2019ottima strategia pu\u00f2 essere attendere un certo periodo di tempo prima di riprovare. Inoltre, quando ci sono fallimenti continui, si pu\u00f2 pensare di aumentare il ritardo tra i tentativi in maniera incrementale o esponenziale al fine di permettere al servizio o alla risorsa di tornare disponibile. Con Polly possiamo implementare questo tipo di Retry mediante il metodo <em>WaitAndRetry<\/em>() che prevede, tra i parametri, il numero di tentativi che si vuole effettuare e un intervallo di tempo che bisogna attendere tra un tentativo e l\u2019altro. In aggiunta, \u00e8 possibile specificare della logica da eseguire prima di ogni tentativo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il delay tra un tentativo e l&#8217;altro pu\u00f2 essere definito in maniera esponenziale (exponential backoff). Tale definizione consente di avere intervalli tra i tentativi che crescono all&#8217;aumentare dei fallimenti consentendo al servizio di avere pi\u00f9 tempo per ritornare a funzionare correttamente. Utilizzando il metodo WaitAndRetry() fornito da Polly, possiamo indicare una base che ad ogni retry verr\u00e0 elevata ad una potenza pari al numero di tentativi effettuati.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n var retryPolicy = Policy.Handle&lt;AlreadyClosedException&gt;() \n            \t.WaitAndRetry(5, \n                retryAttempt =&gt; TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), \n              \t(exception, timeSpan, retryCount, context) =&gt; \n               \t{ \n                Console.WriteLine($&quot;This is the {retryCount} try&quot;); \n               \t} \n            \t); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Visto che l\u2019exponential backoff \u00e8 una progressione fissa, in scenari dove il throughput \u00e8 veramente alto, \u00e8 possibile inoltre introdurre un <em>jitter <\/em>(quantit\u00e0 di tempo aleatoria) per evitare picchi di carico ed introdurre cos\u00ec una certa aleatoriet\u00e0 nel calcolo del delay.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 3) Eseguire il codice attraverso la policy<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stabilita la policy, \u00e8 il momento di eseguirla. Il metodo Execute() conterr\u00e0 la parte di codice che ci interessa, o meglio, quella che pu\u00f2 restituire l\u2019eccezione che vogliamo gestire. Nel nostro caso, si tratta del metodo PublishMessage().&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nretryPolicy.Execute(() =&gt;  \n        PublishMessage(message, channel) \n);  \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Andiamo ad effettuare la simulazione:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_3-1.gif?w=1080&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Se tramite la UI Management di RabbitMQ effettuiamo la GetMessages() possiamo vedere che anche il messaggio inviato dopo la retry \u00e8 arrivato correttamente.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"890\" height=\"864\" data-attachment-id=\"33225\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/attachment\/image_4-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_4.png?fit=890%2C864&amp;ssl=1\" data-orig-size=\"890,864\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image_4\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_4.png?fit=890%2C864&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/image_4.png?resize=890%2C864&#038;ssl=1\" alt=\"\" class=\"wp-image-33225\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/image_4.png 890w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/06\/image_4-480x466.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 890px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Come gi\u00e0 detto questa strategia \u00e8 molto utile nell\u2019affrontare errori transienti o in generale quando gli errori che si vogliono gestire sono temporanei. Non sarebbe efficace, invece, nella gestione di errori di lunga durata. Inoltre, questo approccio non deve essere visto alternativo alla scalabilit\u00e0, in quanto non risolve i problemi di carico. Se ho un sistema a singolo broker e un numero di richieste molto elevato, la strategia di retry pu\u00f2 aiutare nell\u2019inoltrare al broker eventuali messaggi falliti, ma ci\u00f2 non significa che posso affidarmi ad un sistema con meno risorse e ci\u00f2 vale anche se si pensa alle performance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oltre ad approcci reattivi come la strategia di Retry o il <a href=\"https:\/\/github.com\/App-vNext\/Polly\/wiki\/Circuit-Breaker\" target=\"_blank\" rel=\"noreferrer noopener\">Circuit Braker<\/a>, Polly mette sul piatto anche <a href=\"https:\/\/github.com\/App-vNext\/Polly\/wiki\/Transient-fault-handling-and-proactive-resilience-engineering#promoting-resilience-through-a-proactive-stability-oriented-approach\" target=\"_blank\" rel=\"noreferrer noopener\">strategie proattive orientate alla stabilit\u00e0<\/a> ovvero tecniche di resilienza di tipo preventivo. In aggiunta, \u00e8 possibile utilizzare Polly insieme all\u2019HttpClientFactory di ASPNET Core (dalla versione 2.1) per applicare le policies alle chiamate HTTP.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;In chiusura lascio il <a href=\"https:\/\/github.com\/intersect88\/IntroToRabbitMQ\/tree\/RetryStrategy\">link<\/a><a href=\"https:\/\/github.com\/intersect88\/IntroToRabbitMQ\/tree\/RetryStrategy\" target=\"_blank\" rel=\"noreferrer noopener\"> al repository<\/a> dove potete trovare il codice dell\u2019esempio.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al prossimo articolo!&nbsp;<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Vediamo come usare Polly per rendere i nostri sistemi stabili e reattivi agli errori <\/p>\n","protected":false},"author":196716251,"featured_media":33197,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637374],"tags":[688637420,688637457],"class_list":["post-33196","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-net","tag-rabbitmq"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Rendere i sistemi resilienti con Polly - Blexin<\/title>\n<meta name=\"description\" content=\"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Rendere i sistemi resilienti con Polly - Blexin\" \/>\n<meta property=\"og:description\" content=\"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2021-06-22T16:30:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-07-09T15:03:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1105\" \/>\n\t<meta property=\"og:image:height\" content=\"656\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Genny Paudice\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Genny Paudice\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/\"},\"author\":{\"name\":\"Genny Paudice\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/ae0e97a3ebb79d2f73e4411c1eb28973\"},\"headline\":\"Rendere i sistemi resilienti con Polly\",\"datePublished\":\"2021-06-22T16:30:00+00:00\",\"dateModified\":\"2021-07-09T15:03:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/\"},\"wordCount\":1250,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1\",\"keywords\":[\".Net\",\"RabbitMQ\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/\",\"name\":\"Rendere i sistemi resilienti con Polly - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1\",\"datePublished\":\"2021-06-22T16:30:00+00:00\",\"dateModified\":\"2021-07-09T15:03:39+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/ae0e97a3ebb79d2f73e4411c1eb28973\"},\"description\":\"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/06\\\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1\",\"width\":1105,\"height\":656},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/rendere-i-sistemi-resilienti-con-polly\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rendere i sistemi resilienti con Polly\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/ae0e97a3ebb79d2f73e4411c1eb28973\",\"name\":\"Genny Paudice\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g\",\"caption\":\"Genny Paudice\"},\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/author\\\/genny-paudiceblexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Rendere i sistemi resilienti con Polly - Blexin","description":"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern","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:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/","og_locale":"it_IT","og_type":"article","og_title":"Rendere i sistemi resilienti con Polly - Blexin","og_description":"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern","og_url":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/","og_site_name":"Blexin","article_published_time":"2021-06-22T16:30:00+00:00","article_modified_time":"2021-07-09T15:03:39+00:00","og_image":[{"width":1105,"height":656,"url":"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","type":"image\/png"}],"author":"Genny Paudice","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Genny Paudice","Tempo di lettura stimato":"7 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/"},"author":{"name":"Genny Paudice","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/ae0e97a3ebb79d2f73e4411c1eb28973"},"headline":"Rendere i sistemi resilienti con Polly","datePublished":"2021-06-22T16:30:00+00:00","dateModified":"2021-07-09T15:03:39+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/"},"wordCount":1250,"image":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","keywords":[".Net","RabbitMQ"],"articleSection":["Blog"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/","url":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/","name":"Rendere i sistemi resilienti con Polly - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","datePublished":"2021-06-22T16:30:00+00:00","dateModified":"2021-07-09T15:03:39+00:00","author":{"@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/ae0e97a3ebb79d2f73e4411c1eb28973"},"description":"Scopriamo con Genny come Polly viene in nostro aiuto per rendere le applicazioni resilienti utilizzando un Retry Pattern","breadcrumb":{"@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","width":1105,"height":656},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/it\/blog\/rendere-i-sistemi-resilienti-con-polly\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/it\/"},{"@type":"ListItem","position":2,"name":"Rendere i sistemi resilienti con Polly"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/it\/#website","url":"https:\/\/blexin.com\/it\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/ae0e97a3ebb79d2f73e4411c1eb28973","name":"Genny Paudice","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3093a6ee7b7f555e94e4a5d6f19cb09f3af33635007643b2076eb89329789828?s=96&d=identicon&r=g","caption":"Genny Paudice"},"url":"https:\/\/blexin.com\/it\/author\/genny-paudiceblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/06\/11_ITA_1105x656_blog-polly.png?fit=1105%2C656&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-8Dq","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/33196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/users\/196716251"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/comments?post=33196"}],"version-history":[{"count":22,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/33196\/revisions"}],"predecessor-version":[{"id":33250,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/33196\/revisions\/33250"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media\/33197"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media?parent=33196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/categories?post=33196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/tags?post=33196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}