{"id":9384,"date":"2023-11-21T14:02:10","date_gmt":"2023-11-21T17:02:10","guid":{"rendered":"https:\/\/elemarjr.com\/clube-de-estudos\/?post_type=artigos&#038;p=9384"},"modified":"2023-12-27T08:47:21","modified_gmt":"2023-12-27T11:47:21","slug":"voce-ja-ouviu-falar-em-back-pressure","status":"publish","type":"artigos","link":"https:\/\/elemarjr.com\/clube-de-estudos\/artigos\/voce-ja-ouviu-falar-em-back-pressure\/","title":{"rendered":"Voc\u00ea j\u00e1 ouviu falar em Back Pressure?"},"content":{"rendered":"\n<p>Nas aplica\u00e7\u00f5es cliente-servidor, uma quest\u00e3o inescap\u00e1vel \u00e9 o gerenciamento eficiente da alta carga de requisi\u00e7\u00f5es que um servidor pode suportar. Imagine um cen\u00e1rio em que centenas ou milhares de clientes bombardeiam um servidor web simultaneamente. Como ele pode gerenciar essa carga sem sucumbir \u00e0 press\u00e3o?<\/p>\n\n\n\n<p>A\u00ed entra o conceito de <em>back pressure<\/em>, vital na arquitetura de sistemas distribu\u00eddos. Semelhante \u00e0 press\u00e3o excessiva em um cano que deve ser equalizada para evitar danos, o servidor precisa de um sistema que equilibre a carga para manter a estabilidade. Mas como exatamente isso \u00e9 implementado?<\/p>\n\n\n\n<p>Vamos a um exemplo pr\u00e1tico em c\u00f3digo C#. Imagine que temos um servidor web ASP.NET Core. Podemos utilizar middlewares para aplicar limita\u00e7\u00e3o de taxa (<em>rate limiting<\/em>) e tratar o <em>back pressure<\/em>. Abaixo, um pseudo-c\u00f3digo simplificado de como poderia ser um middleware de <em>rate limiting<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" style=\"font-size:.875rem;line-height:1.25rem\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"public class RateLimitingMiddleware\n{\n    private readonly RequestDelegate _next;\n    private readonly int _requestLimit;\n    private int _requestCount;\n\n    public RateLimitingMiddleware(RequestDelegate next, int requestLimit)\n    {\n        _next = next;\n        _requestLimit = requestLimit;\n        _requestCount = 0;\n    }\n\n    public async Task InvokeAsync(HttpContext context)\n    {\n        if (_requestCount &gt;= _requestLimit)\n        {\n            context.Response.StatusCode = StatusCodes.Status429TooManyRequests;\n            return;\n        }\n\n        Interlocked.Increment(ref _requestCount);\n        try\n        {\n            await _next(context);\n        }\n        finally\n        {\n            Interlocked.Decrement(ref _requestCount);\n        }\n    }\n}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\"><code><span class=\"line\"><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">class<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #8FBCBB\">RateLimitingMiddleware<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">readonly<\/span><span style=\"color: #D8DEE9FF\"> RequestDelegate _next<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">readonly<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">int<\/span><span style=\"color: #D8DEE9FF\"> _requestLimit<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">private<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">int<\/span><span style=\"color: #D8DEE9FF\"> _requestCount<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">RateLimitingMiddleware<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">RequestDelegate next<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">int<\/span><span style=\"color: #D8DEE9FF\"> requestLimit<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">_next<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">next<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">_requestLimit<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">requestLimit<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">_requestCount<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">0<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">async<\/span><span style=\"color: #D8DEE9FF\"> Task <\/span><span style=\"color: #88C0D0\">InvokeAsync<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">HttpContext context<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">_requestCount<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_requestLimit<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">context<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Response<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">StatusCode<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">StatusCodes<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Status429TooManyRequests<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">return;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #D8DEE9\">Interlocked<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Increment<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">ref<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_requestCount<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">await<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">_next<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">context<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">finally<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">Interlocked<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">Decrement<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">ref<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">_requestCount<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Este middleware controla o n\u00famero de requisi\u00e7\u00f5es concorrentes e rejeita qualquer nova requisi\u00e7\u00e3o com um status HTTP 429 assim que o limite \u00e9 alcan\u00e7ado, indicando ao cliente que deve tentar novamente mais tarde.<\/p>\n\n\n\n<p><em>Back pressure<\/em> pode envolver t\u00e9cnicas mais sofisticadas, como filas e sistemas de mensagens, onde a carga \u00e9 gerenciada distribuindo-a uniformemente. A ideia n\u00e3o \u00e9 simplesmente rejeitar o excesso, mas comunicar de volta ao cliente, potencialmente com uma mensagem como &#8220;Tente novamente ap\u00f3s X segundos&#8221;, para que ambos, cliente e servidor, possam se ajustar de maneira din\u00e2mica e inteligente.<\/p>\n\n\n\n<p>Al\u00e9m disso, examinemos a degrada\u00e7\u00e3o graciosa. Um exemplo deste conceito \u00e9 um servi\u00e7o web que, sob carga pesada, desativa temporariamente funcionalidades secund\u00e1rias para dedicar recursos \u00e0s fun\u00e7\u00f5es cr\u00edticas, mantendo o servi\u00e7o operando, embora em capacidade reduzida.<\/p>\n\n\n\n<p>Um caso conhecido de aplica\u00e7\u00e3o bem-sucedida de t\u00e9cnicas de <em>back pressure<\/em> e degrada\u00e7\u00e3o graciosa \u00e9 o da Netflix. A plataforma utiliza uma s\u00e9rie de padr\u00f5es de resili\u00eancia para gerenciar a distribui\u00e7\u00e3o de conte\u00fado para milh\u00f5es de usu\u00e1rios. Diante de uma falha ou sobrecarga, seus sistemas s\u00e3o projetados para degradar de maneira controlada, preservando a experi\u00eancia do usu\u00e1rio final.<\/p>\n\n\n\n<p>Finalmente, vale a pena mencionar as pr\u00e1ticas de teste de carga e simula\u00e7\u00f5es de falha. Estas s\u00e3o ferramentas preciosas para validar a robustez de uma arquitetura contra cen\u00e1rios de alta demanda. Frameworks como Gatling ou JMeter podem ser utilizados para simular requisi\u00e7\u00f5es em massa e avaliar como a aplica\u00e7\u00e3o sob teste responde a <em>back pressure<\/em>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Conclus\u00e3o<\/h1>\n\n\n\n<p>Abordar conceitos como <em>back pressure<\/em>, <em>rate limiting<\/em> e degrada\u00e7\u00e3o graciosa significa entender os alicerces da resili\u00eancia em arquitetura de software. Essas estrat\u00e9gias s\u00e3o fundamentais para que sistemas distribu\u00eddos se mantenham confi\u00e1veis sob demandas vari\u00e1veis. A aplica\u00e7\u00e3o pr\u00e1tica desses conceitos, refor\u00e7ada por exemplos reais e testes rigorosos, \u00e9 um passo crucial para arquitetos e desenvolvedores. Estes temas, suas implementa\u00e7\u00f5es e pr\u00e1ticas associadas s\u00e3o explorados em profundidade em meus grupos de estudos e mentorias, permitindo aprofundar o conhecimento e compartilhar experi\u00eancias.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">TL;DR<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><em>Back pressure<\/em> \u00e9 um conceito essencial para a gest\u00e3o de alta carga em servidores, assegurando estabilidade e evitando sobrecarga.<\/li>\n\n\n\n<li>Exemplos em C# e a aplica\u00e7\u00e3o de middlewares no ASP.NET Core ilustram como realizar <em>rate limiting<\/em> em aplica\u00e7\u00f5es pr\u00e1ticas.<\/li>\n\n\n\n<li>Casos reais como o da Netflix exemplificam a implementa\u00e7\u00e3o de degrada\u00e7\u00e3o graciosa e pr\u00e1ticas de teste de carga s\u00e3o vitais para validar a resili\u00eancia da arquitetura de software.<\/li>\n<\/ol>\n","protected":false},"featured_media":9385,"parent":0,"template":"","cursos":[16],"class_list":["post-9384","artigos","type-artigos","status-publish","has-post-thumbnail","hentry","cursos-arquitetura-de-software"],"acf":[],"_links":{"self":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/artigos\/9384","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/artigos"}],"about":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/types\/artigos"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/media\/9385"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/media?parent=9384"}],"wp:term":[{"taxonomy":"cursos","embeddable":true,"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/cursos?post=9384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}