{"id":4355,"date":"2022-07-03T17:15:30","date_gmt":"2022-07-03T20:15:30","guid":{"rendered":"https:\/\/elemarjr.com\/arquiteturadesoftware\/?p=4355"},"modified":"2024-01-12T18:05:22","modified_gmt":"2024-01-12T21:05:22","slug":"fundamentos-para-arquiteturas-de-sistemas-resilientes","status":"publish","type":"volume-1","link":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/","title":{"rendered":"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes"},"content":{"rendered":"<p><strong><em>Software<\/em> \u00e9 cada vez mais importante.<\/strong> Hoje em dia, \u00e9 dif\u00edcil imaginar qualquer atividade relevante, dentro e fora das organiza\u00e7\u00f5es, que n\u00e3o seja suportada direta ou indiretamente por <em>software<\/em>.<\/p>\n<p><strong>Quando <em>software<\/em> n\u00e3o funciona a produtividade \u00e9 prejudicada.\u00a0<\/strong>Muitas vezes, o trabalho \u00e9 interrompido e resultados deixam de ser atingidos. Em cen\u00e1rios extremos, <em>software<\/em> que n\u00e3o funciona coloca vidas em risco.<\/p>\n<p><strong><em>Software<\/em> est\u00e1 se tornando cada vez mais complexo<\/strong>. Expectativas est\u00e3o cada vez mais altas, sistemas est\u00e3o ficando cada vez mais conectados, cargas de trabalho t\u00eam variado em propor\u00e7\u00f5es crescentes, prazos para desenvolvimento de inova\u00e7\u00f5es e adapta\u00e7\u00f5es est\u00e3o cada vez menores.<\/p>\n<p><strong>Nesse contexto, fica evidente a import\u00e2ncia crescente da resili\u00eancia.<\/strong><\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Defini\u00e7\u00e3o: Resili\u00eancia<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\"><\/p>\n<p>Resili\u00eancia \u00e9 um atributo de qualidade observado em sistemas que conseguem se adaptar para suportar condi\u00e7\u00f5es adversas, atendendo continuamente as especifica\u00e7\u00f5es, retomando, de maneira autom\u00e1tica, quando poss\u00edvel, sua configura\u00e7\u00e3o ideal.<\/p>\n<p><\/p>\r\n<\/div>\n<h2>Defeito (<em>failure<\/em>), erro (<em>error<\/em>) e falha (<em>fault<\/em>)<\/h2>\n<p><strong>O desenvolvimento de arquiteturas resilientes implica no perfeito entendimento e diferencia\u00e7\u00e3o de tr\u00eas conceitos fundamentais: defeitos, erros, e falhas.<\/strong><\/p>\n<h4>Defeitos (<em>failures<\/em>)<\/h4>\n<p><strong>Um software \u00e9 dito defeituoso quando se mostra incapaz de operar de acordo com suas especifica\u00e7\u00f5es<\/strong> &#8211; ou seja, a descri\u00e7\u00e3o aceita de funcionalidades que atendem os objetivos de neg\u00f3cio, respeitando restri\u00e7\u00f5es, atingindo determinados par\u00e2metros em seus atributos de qualidade.<\/p>\n<p>Os tipos mais comuns de defeitos percebidos em sistemas s\u00e3o: 1) <em>crashes\u00a0<\/em>inesperados; 2) gera\u00e7\u00e3o de resultados incorretos e 3) indisponibilidades.<\/p>\n<p><strong>A condi\u00e7\u00e3o defeituosa de um sistema \u00e9 percept\u00edvel por seus usu\u00e1rios ou por mecanismos de monitoramento.<\/strong><\/p>\n<p><strong>Defeitos s\u00e3o causados por erros.<\/strong><\/p>\n<h4>Erros (<em>errors<\/em>)<\/h4>\n<p><strong>Um erro \u00e9 um comportamento inadequado de um sistema que pode originar um defeito.\u00a0<\/strong>Eles t\u00eam rela\u00e7\u00e3o com valores que um software gera ou armazena e, tamb\u00e9m, com montantes de tempo demandados para execu\u00e7\u00e3o do trabalho.<\/p>\n<p>O projeto cuidadoso da arquitetura deve identificar, o mais cedo poss\u00edvel, a ocorr\u00eancia de erros de forma a &#8220;recuperar&#8221; o sistema.<\/p>\n<p>Alguns exemplos comuns de erros s\u00e3o: 1) <em>time<\/em> e\u00a0<em>race\u00a0<\/em>conditions; 2)\u00a0<em>loops\u00a0<\/em>infinitos; 3) desrespeito a protocolos quanto a formato de mensagens, sequ\u00eancia, pr\u00e9-condi\u00e7\u00f5es, p\u00f3s-condi\u00e7\u00f5es ou invariantes; 4) inconsist\u00eancia de dados e; 5) incapacidade para suportar o\u00a0<em>workload<\/em>.<\/p>\n<h4>Falhas (<em>faults<\/em>)<\/h4>\n<p><strong>Uma falha \u00e9 uma inconformidade, presente no sistema, que pode causar um erro.<\/strong><\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Duas constata\u00e7\u00f5es s\u00e3o inquestion\u00e1veis em um mundo cada vez mais digital. A primeira \u00e9 que as especifica\u00e7\u00f5es de qualquer <em>software<\/em> relevante ser\u00e3o modificadas com frequ\u00eancias cada vez maiores. A segunda \u00e9 que falhas s\u00e3o inevit\u00e1veis!<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Tr\u00eas tipos (muito) diferentes de defeitos<\/h2>\n<p><strong>Defeitos podem ser classificados em tr\u00eas tipos: inconsistentes, consistentes ou <em>fail-stop<\/em>.<\/strong><\/p>\n<h4>Defeitos inconsistentes<\/h4>\n<p>O pior tipo de defeito que um software pode apresentar \u00e9 o &#8220;inconsistente&#8221;.<\/p>\n<p><strong>Um defeito \u00e9 dito inconsistente quando \u00e9 manifesto de formas diferentes (com varia\u00e7\u00f5es percebidas no tempo ou conforme o observador). <\/strong>Um bom exemplo desse tipo de defeito \u00e9 quando um artefato n\u00e3o responde para determinados clientes, fornece respostas incorretas para outros, sem indicar anomalias percept\u00edveis para sistemas de monitoramento.<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Byzantine Failures<\/p>\r\n<\/p>\n<p>Defeitos inconsistentes tamb\u00e9m s\u00e3o conhecidos como\u00a0<em>Byzantine Failiures<\/em>.<\/p>\n<p>&#8220;Contornar&#8221; defeitos bizantinos demanda estrat\u00e9gias complexas de\u00a0<em>clustering <\/em>adotando, eventualmente, protocolos de consenso como\u00a0<em>Paxos\u00a0<\/em>e\u00a0<em>Raft.<\/em><\/p>\n<p><\/div>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-livro-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"https:\/\/sd.arquiteturadesoftware.online\/wp-content\/uploads\/2022\/06\/livro-arquitetura-sd.png\" alt=\"\" width=\"150\" \/><\/td>\r\n<td class=\"nota-livro-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"https:\/\/sd.arquiteturadesoftware.online\/wp-content\/uploads\/2022\/06\/livro-arquitetura-sd.png\" alt=\"\" width=\"150\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; color: #4c4c4c; line-height: 1.0; font-family: Lufga; margin-bottom: 10px;\">Entendendo o protocolo Raft<\/p>\r\n<p style=\"font-size: 20px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Lufga; margin-bottom: 10px;\">Manual do Arquiteto de Software: Sistemas distribu\u00eddos<\/p>\r\n<\/p>\n<p>Neste cap\u00edtulo apresento um protocolo chamado\u00a0<em>Raft<\/em>. Uma solu\u00e7\u00e3o poss\u00edvel para o problema de garantir consenso entre unidades de processamento em sistemas distribu\u00eddos.<\/p>\n<p>\r\n<p><a class=\"botao-livro\" href=\"https:\/\/sd.arquiteturadesoftware.online\/entendendo-o-protocolo-raft-capitulo-1-v-1-0\/\" target=\"_blank\" rel=\"noopener\">Ler cap\u00edtulo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Para um determinado componente que precise ser tolerante a falhas que ocasionem defeitos inconsistentes ser\u00e3o necess\u00e1rias <em>3n+1\u00a0<\/em>r\u00e9plicas (onde <em>n <\/em>corresponde a quantidade de tipos de falhas).<\/p>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-contribuicao-2\">\r\n<p style=\"font-size: 22px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Practical Byzantine Fault Tolerance and Proactive Recovery<\/p>\r\nEm 1999, Miguel Castro e Barbara Liskov apresentaram um algoritmo, avan\u00e7ado, para contornar falhas bizantinas de maneira extremamente eficiente.\r\n<p><a class=\"botao-livro\" href=\"https:\/\/pmg.csail.mit.edu\/papers\/bft-tocs.pdf\" target=\"_blank\" rel=\"noopener\">Acessar<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h4>Defeitos consistentes<\/h4>\n<p><strong>A segunda categoria de defeitos \u00e9 a daqueles ditos &#8220;consistentes&#8221;. Ou seja, manifesta\u00e7\u00f5es dos &#8220;mesmos erros&#8221; independente de tempo de execu\u00e7\u00e3o ou mecanismo observador.\u00a0<\/strong><\/p>\n<p>Para um determinado componente que precise ser tolerante a falhas que ocasionem defeitos consistentes ser\u00e3o necess\u00e1rias 2<em>n+1\u00a0<\/em>r\u00e9plicas (onde <em>n <\/em>corresponde a quantidade de tipos de falhas).<\/p>\n<h4>Defeitos <em>fail-stop<\/em><\/h4>\n<p><strong>A \u00faltima categoria de defeitos \u00e9 aquela onde falhas (<em>fail-silent<\/em>) causam interrup\u00e7\u00e3o imediata no funcionamento do componente (<em>crash failure<\/em>) que a manifesta.<\/strong><\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Defini\u00e7\u00e3o: Fail-silent<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\"><\/p>\n<p>Uma falha \u00e9 dita &#8220;silenciosa&#8221; quando n\u00e3o impede um componente de produzir resultados corretos ou quando, em outro extremo, o impede de produzir quaisquer resultados.<\/p>\n<p><\/p>\r\n<\/div>\n<p>Para um determinado componente que precise ser tolerante a falhas que ocasionem defeitos <em>fail-stop<\/em> ser\u00e3o necess\u00e1rias <em>n+1\u00a0<\/em>r\u00e9plicas (onde <em>n <\/em>corresponde a quantidade de tipos de falhas).<\/p>\n<div class=\"nota-youtube\">\r\n<table class=\"tabelayoutube\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-youtube-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/><\/td>\r\n<td class=\"nota-youtube-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">The Power of Abstraction<\/p>\r\nEm 2009, Barbara Liskov, um dos maiores nomes na hist\u00f3ria da computa\u00e7\u00e3o, compartilhou sua percep\u00e7\u00e3o a respeito da computa\u00e7\u00e3o e de abstra\u00e7\u00f5es. Palestra imperd\u00edvel.\r\n<p><a class=\"botao-youtube\" href=\"https:\/\/www.youtube.com\/watch?v=qAKrMdUycb8\" target=\"_blank\" rel=\"noopener\" style=\"margin-top: 20px;\">Acessar v\u00eddeo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>M\u00e9tricas relacionadas a resili\u00eancia<\/h2>\n<div class=\"nota-alerta\">\r\n<table class=\"tabelaalerta\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-citacao\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/> <\/p>\n<p><em>N\u00e3o se gerencia o que n\u00e3o se mede, n\u00e3o se mede o que n\u00e3o se define, n\u00e3o se define o que n\u00e3o se entende, e n\u00e3o h\u00e1 sucesso no que n\u00e3o se gerencia.<\/em><\/p>\n<p>\r\n<p><strong>William Edwards Deming<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>H\u00e1 tr\u00eas indicadores importantes para determinar o n\u00edvel de resili\u00eancia de um sistema:\u00a0<em>coverage<\/em>,\u00a0<em>reliability\u00a0<\/em>e\u00a0<em>availability.<\/em><\/p>\n<h4>\u00cdndice de Cobertura (<em>Coverage factor<\/em>)<\/h4>\n<p>O \u00edndice de cobertura \u00e9 calculado com base na probabilidade de identificar a ocorr\u00eancia de um determinado tipo de falha e da probabilidade do sistema conseguir se recuperar plenamente, automaticamente, em um tempo considerado razo\u00e1vel.<\/p>\n<h4>Confiabilidade (<em>Reliability<\/em>)<\/h4>\n<p>Confiabilidade \u00e9 a probabilidade de um sistema produzir os resultados esperados, comportando-se conforme a especifica\u00e7\u00e3o.<\/p>\n<p>De forma simplificada, podemos assumir confiabilidade como sendo:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-5017\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2022\/07\/reliability_.png\" alt=\"\" width=\"166\" height=\"45\" \/><\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">MTTF, MTTR e MTBF<\/p>\r\n<\/p>\n<p>Tr\u00eas m\u00e9tricas s\u00e3o frequentemente associadas com confiabilidade.<\/p>\n<p><em>MTTF<\/em> \u00e9 o tempo m\u00e9dio para falhas, ou seja, entre um sistema entrar em opera\u00e7\u00e3o e entrar em estado falho.<\/p>\n<p><em>MTTR<\/em> \u00e9 o tempo m\u00e9dio para um sistema se recuperar de falhas, ou seja, entre entrar em estado falho e estar recuperado.<\/p>\n<p><em>MTBF<\/em> \u00e9 a soma de <em>MTTF<\/em> e <em>MTTR<\/em>.<\/p>\n<p><\/div>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-livro-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"https:\/\/m.media-amazon.com\/images\/I\/51XswOmuLqL.jpg\" alt=\"\" width=\"150\" \/><\/td>\r\n<td class=\"nota-livro-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"https:\/\/m.media-amazon.com\/images\/I\/51XswOmuLqL.jpg\" alt=\"\" width=\"150\" \/>\r\n<p style=\"font-size: 20px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Site Reliability Engineering: How Google Runs Production Systems <\/p>\r\nEste livro j\u00e1 pode ser considerado um cl\u00e1ssico. Ele formaliza SRE &#8211; conjunto de pr\u00e1ticas para resili\u00eancia da Google.\r\n<p><a class=\"botao-livro\" href=\"https:\/\/www.amazon.com.br\/Site-Reliability-Engineering-Production-Systems-ebook\/dp\/B01DCPXKZ6\" target=\"_blank\" rel=\"noopener\">Acessar livro<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h4>Disponibilidade (<em>Availability<\/em>)<\/h4>\n<p>A disponibilidade \u00e9 a propor\u00e7\u00e3o do tempo em\u00a0<em>uptime<\/em> (MTTF) e o tempo total em opera\u00e7\u00e3o, considerando o tempo em <em>downtime <\/em>(MTTF + MTTR).<\/p>\n<h2><em>Mindset<\/em> para cria\u00e7\u00e3o de sistemas resilientes<\/h2>\n<p><strong>Um defeito pode ser causado pela ocorr\u00eancia de diferentes tipos de erros que, por sua vez, podem ser causados por diversas\u00a0 falhas. <\/strong>Por exemplo, um sistema de <em>e-commerce<\/em> ser\u00e1 defeituoso caso n\u00e3o consiga gerar pedidos assertivamente. Pedidos estar\u00e3o &#8220;errados&#8221; quando relacionarem itens n\u00e3o solicitados pelos clientes ou quando, por outro lado, deixarem de relacionar itens solicitados. As falhas que podem gerar esses dois erros, por sua vez, s\u00e3o diversas.<\/p>\nO <em>mindset <\/em>para cria\u00e7\u00e3o de sistemas resilientes \u00e9 desenvolvido pelo h\u00e1bito de questionar, continuamente, em todas as atividades de engenharia, o que pode potencialmente dar errado como resultante do trabalho que est\u00e1 sendo realizado ou das decis\u00f5es que est\u00e3o sendo tomadas.\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> O arquiteto de software colabora com a resili\u00eancia, questionando especialistas sobre potenciais fontes de falha e registrando respostas nas ADRs.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\nTimes com\u00a0<em>mindset\u00a0<\/em>resiliente empregam pr\u00e1ticas de programa\u00e7\u00e3o defensiva, adotam pontos de tens\u00e3o (como em metodologias de\u00a0<em>chaos engineering\u00a0<\/em>para, de forma respons\u00e1vel, identificar e mitigar falhas), adotam testes automatizados, invariavelmente adicionam redund\u00e2ncia ao projetar <em>design<\/em>, utilizam ferramentas de an\u00e1lise est\u00e1tica.\n<div class=\"nota-youtube\">\r\n<table class=\"tabelayoutube\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-youtube-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/><\/td>\r\n<td class=\"nota-youtube-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Deprecating Simplicity 3.0<\/p>\r\n<\/p>\n<p>Nesta palestra, <a href=\"https:\/\/www.linkedin.com\/in\/caseyrosenthal\/\">Casey Rosenthal<\/a>, idealizador do\u00a0<em>Chaos Engineering,\u00a0<\/em>compartilha suas percep\u00e7\u00f5es sobre gest\u00e3o da complexidade e resili\u00eancia. Imperd\u00edvel!<\/p>\n<p>\r\n<p><a class=\"botao-youtube\" href=\"https:\/\/www.youtube.com\/watch?v=JfT9UxcEcOE\" target=\"_blank\" rel=\"noopener\" style=\"margin-top: 20px;\">Acessar v\u00eddeo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<div class=\"nota-livro\">\r\n<table class=\"tabelalivro\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-livro-coluna-1\" valign=\"top\"><img decoding=\"async\" src=\"https:\/\/m.media-amazon.com\/images\/I\/419zAwJJH4L.jpg\" alt=\"\" width=\"150\" \/><\/td>\r\n<td class=\"nota-livro-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"https:\/\/m.media-amazon.com\/images\/I\/419zAwJJH4L.jpg\" alt=\"\" width=\"150\" \/>\r\n<p style=\"font-size: 20px; font-weight: bold; color: #4c4c4c; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Release It!<\/p>\r\nSem d\u00favidas, um dos melhores livros j\u00e1 escritos sobre projeto de sistemas resilientes.\r\n<p><a class=\"botao-livro\" href=\"https:\/\/www.amazon.com.br\/Release-Design-Production-Ready-Software-English-ebook\/dp\/B079YWMY2V\/\" target=\"_blank\" rel=\"noopener\">Acessar livro<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Iniciativas arquiteturais para resili\u00eancia<\/h2>\n<p>Sob o ponto de vista da arquitetura de software, o projeto de sistemas resilientes implica em considerar, nas decis\u00f5es de <em>design\u00a0<\/em>alternativas, para: 1) detectar a ocorr\u00eancia erros; 2) recuperar o sistema de um erro; 3) impedir a propaga\u00e7\u00e3o e; 4) tratar falhas.<\/p>\n<p>Aten\u00e7\u00e3o especial deve ser dada as estrat\u00e9gias que ser\u00e3o empregadas para suportar a carga no per\u00edodo entre um erro ser detectado e o sistema estar plenamente recuperado e pronto para continuar (MTTR).<\/p>\n<h4>Modularizar considerando unidades de mitiga\u00e7\u00e3o<\/h4>\n<p>Uma das principais atribui\u00e7\u00f5es do <em>design <\/em>arquitetural \u00e9 segmentar responsabilidades em m\u00f3dulos de forma a reduzir a complexidade. <strong>Sob a perspectiva do desenvolvimento de sistemas resilientes, a modulariza\u00e7\u00e3o tamb\u00e9m deve levar em conta a possibilidade de criar &#8220;unidades de mitiga\u00e7\u00e3o&#8221;.<\/strong><\/p>\n<p><strong>Todo m\u00f3dulo ou componente em uma arquitetura \u00e9, por defini\u00e7\u00e3o, uma unidade de mitiga\u00e7\u00e3o<\/strong>. Afinal, pode possuir estrat\u00e9gias para detectar e impedir a propaga\u00e7\u00e3o de erros que coloquem o sistema inteiro em estado defeituoso.<\/p>\n<p>Unidades de mitiga\u00e7\u00e3o bem delimitadas habilitam o uso eficiente de mecanismos de\u00a0<em>failover\u00a0<\/em>(tais como\u00a0<em>fallbacks<\/em>). Al\u00e9m disso, isolam interven\u00e7\u00f5es para detec\u00e7\u00e3o de erros e para recupera\u00e7\u00e3o.<\/p>\n<h4>Adicionar mecanismos de auditoria e corre\u00e7\u00e3o de dados<\/h4>\n<p>Par\u00e2metros falhos, geram dados falhos que colocam sistemas em estados falhos que, eventualmente, causam erros.<\/p>\n<p>O projeto arquitetural deve considerar, com muito cuidado, comunica\u00e7\u00f5es, sobretudo entre unidades de mitiga\u00e7\u00e3o, de forma a validar que contratos est\u00e3o sendo respeitados &#8211; adicionando verifica\u00e7\u00f5es para pr\u00e9-condi\u00e7\u00f5es, p\u00f3s-condi\u00e7\u00f5es e invariantes.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Volumes maiores de dados ou dados sens\u00edveis devem ser assinados e verificados.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\nEventualmente, implementa\u00e7\u00f5es alternativas para um mesmo servi\u00e7o podem ser executados, paralelamente, tanto para melhorar o desempenho percebido quanto para comparar resultados.\n<h4>Adotar estrat\u00e9gias de redund\u00e2ncia adequadas ao tipo de erros<\/h4>\n<p>Como minimizar os impactos percebidos no per\u00edodo entre um erro ser detectado em um componente, em produ\u00e7\u00e3o, e o procedimento de recupera\u00e7\u00e3o estar conclu\u00eddo? Adotando redund\u00e2ncia adequada, tanto em funcionamento quando em quantidade.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Lembre-se, tipos diferentes de defeitos demandam volumes diferentes de redund\u00e2ncia.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h4>Adotar redund\u00e2ncia adequada considerando <em>workloads<\/em><\/h4>\n<div class=\"nota-alerta\">\r\n<table class=\"tabelaalerta\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-citacao\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/> <\/p>\n<p><em>Esperan\u00e7a n\u00e3o \u00e9 estrat\u00e9gia.<\/em><\/p>\n<p>\r\n<p><strong>Frase popular entre praticantes de SRE<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Considere um sistema que precise suportar, consistentemente, 1.000 requisi\u00e7\u00f5es por segundo. Cada servidor de aplica\u00e7\u00e3o deste sistema demonstra capacidade para suportar 300 requisi\u00e7\u00f5es por segundo. Da\u00ed, infere-se a necessidade de quatro inst\u00e2ncias.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4366 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4.png\" alt=\"\" width=\"456\" height=\"333\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4.png 912w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4-300x219.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4-768x561.png 768w\" sizes=\"(max-width: 456px) 100vw, 456px\" \/><\/p>\n<p>O problema \u00e9 que uma eventual indisponibilidade em um dos servidores implica em sobrecarga para as demais inst\u00e2ncias.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4367 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4f.png\" alt=\"\" width=\"456\" height=\"333\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4f.png 912w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4f-300x219.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/server_4f-768x561.png 768w\" sizes=\"(max-width: 456px) 100vw, 456px\" \/><\/p>\n<p>Com o <em>traffic intensity\u00a0<\/em>desfavor\u00e1vel (<em>arrival rate<\/em> &gt; <em>departure rate<\/em>) ocorre, ent\u00e3o, prov\u00e1vel satura\u00e7\u00e3o de recursos (falha) levando a erros e defeitos (indisponibilidade do servi\u00e7o) em, provavelmente, pouco tempo.<\/p>\n<div class=\"nota-link\">\r\n<table class=\"tabelalink\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-insight\" src=\"\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/link.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/link.png\" alt=\"\" width=\"70\" height=\"70\" \/>\r\n<p style=\"font-size: 22px; font-weight: bold; line-height: 26px; font-family: Montserrat; color: #432b75; margin-bottom: 5px;\">Filas geram satura\u00e7\u00e3o<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d; margin-bottom: 0px;\">A forma\u00e7\u00e3o de filas, invariavelmente, gera satura\u00e7\u00e3o de recursos, eventualmente gerando indisponibilidades. Interessado em saber mais?<\/p>\r\n<a class=\"botao-livro\" href=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/fundamentos-para-arquitetura-de-sistemas-com-bom-desempenho-capitulo-2-3-v-3-0\/#Relacao_com_filas\" target=\"_blank\" rel=\"noopener\">Acessar t\u00f3pico<\/a><\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>A estrat\u00e9gia para resili\u00eancia, no exemplo, consiste em adicionar redund\u00e2ncia. Em termos simples, um quinto servidor &#8220;sobrando&#8221; seria a forma evidente para tolerar falhas.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Redund\u00e2ncia, essencial para resili\u00eancia, implica em aumento de custos.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>N\u00e3o h\u00e1 resili\u00eancia sem redund\u00e2ncia. Entretanto, esta \u00e9 apenas a primeira medida e, provavelmente, a mais cara.<\/p>\n<h4>Adotar\u00a0<em>recovery blocks\u00a0<\/em>e <em>fallbacks<\/em><\/h4>\n<p>Unidades de mitiga\u00e7\u00e3o cr\u00edticas para o funcionamento de um sistema devem, invariavelmente, possuir mecanismos de\u00a0<em>fallback.<\/em><\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Defini\u00e7\u00e3o: Fallback<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\"><\/p>\n<p><em>Fallback\u00a0<\/em> \u00e9 uma alternativa de substitui\u00e7\u00e3o para uma determinada unidade de mitiga\u00e7\u00e3o, capaz de cumprir sua premissa funcional enquanto ela estiver indispon\u00edvel ou invi\u00e1vel.<\/p>\n<p><\/p>\r\n<\/div>\n<p>Eventualmente, deve-se considerar o desenvolvimento de implementa\u00e7\u00f5es alternativas (<em>recovery blocks<\/em>), dentro de uma mesma organiza\u00e7\u00e3o, para uma mesma unidade de mitiga\u00e7\u00e3o, como forma de mitigar as chances de falhas de c\u00f3digo ou de entendimento.<\/p>\n<h4>Projetar interfaces administrativas<\/h4>\n<p>A execu\u00e7\u00e3o de atividades administrativas devem ter pouco impacto no desempenho de uma solu\u00e7\u00e3o. Idealmente, elas est\u00e3o apartadas e permitem a execu\u00e7\u00e3o de opera\u00e7\u00f5es corretivas, bem como verifica\u00e7\u00f5es de sanidade (como <em>health checkers<\/em>).<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Readiness e Liveness<\/p>\r\n<\/p>\n<p>A ado\u00e7\u00e3o de tecnologias como Kubernetes levaram a uma amplia\u00e7\u00e3o do conceito de <em>health checking<\/em>. Modernamente admite-se dois tipos diferentes de verifica\u00e7\u00e3o: <em>readiness<\/em> e <em>liveness<\/em>.<\/p>\n<p><em>Readiness\u00a0<\/em>trata da &#8220;prontid\u00e3o&#8221; de um\u00a0<em>pod\u00a0<\/em>para tratar <em>workload<\/em>. Tal prontid\u00e3o \u00e9 impactada pelo\u00a0<em>pod\u00a0<\/em>em si, mas, tamb\u00e9m, por suas depend\u00eancias.<\/p>\n<p><em>Liveness\u00a0<\/em>trata da sa\u00fade de um\u00a0<em>pod.\u00a0<\/em>\u00c9 indicativo para a necessidade de &#8220;reciclagem&#8221;.<\/p>\n<p><\/div>\n<p>Eventualmente, as verifica\u00e7\u00f5es podem incluir as principais depend\u00eancias dos componentes, como bancos de dados, servi\u00e7os remotos, etc.<\/p>\n<p>\u00c9 importante configurar adequadamente mecanismos de <em>health check<\/em> com intervalos e alguma estrutura de <em>caching<\/em> para evitar sobrecargas desnecess\u00e1rias.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Considere ter duas vers\u00f5es de <em>healthcheckers: <\/em>para consumo interno e para consumo externo.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Interfaces administrativas devem ser projetadas para operar em n\u00edvel de seguran\u00e7a diferentes.<\/p>\n<h4>Projetar agentes e crit\u00e9rios de decis\u00e3o e <em>escalation<\/em><\/h4>\n<p>Agentes de decis\u00e3o s\u00e3o componentes de software, como <em>watchdogs<\/em>, desenvolvidos interna ou externamente, que consomem as interfaces administrativas afim de detectar a ocorr\u00eancia de defeitos em componentes do software, eventualmente, disparando a\u00e7\u00f5es corretivas.<\/p>\n<div><\/div>\n<p>Enquanto <em>health checks<\/em> operam passivamente, fornecendo informa\u00e7\u00f5es sobre a &#8220;sa\u00fade&#8221; dos componentes,\u00a0<em>watchdogs\u00a0<\/em>atuam ativamente, muitas vezes acionando\u00a0<em>health checks,\u00a0<\/em>para, sob determinadas circunst\u00e2ncias, disparar algum tipo de a\u00e7\u00e3o.<\/p>\n<p>Um <em>watchdog<\/em> \u00e9 um programa, frequentemente associado a ferramentas de APM e m\u00e9tricas de infraestrutura. Seu objetivo \u00e9 detectar automaticamente poss\u00edveis problemas de aplicativo e infraestrutura, observando continuamente tend\u00eancias e padr\u00f5es nas m\u00e9tricas e procurando comportamento at\u00edpico.<\/p>\n<h4>Adotar comunica\u00e7\u00e3o ass\u00edncrona<\/h4>\n<p><strong>Substituir chamadas diretas por trocas de mensagens \u00e9, provavelmente, a medida mais eficiente para aumentar a resili\u00eancia de sistemas de software.\u00a0<\/strong>A ideia \u00e9 substituir chamadas a componentes potencialmente inst\u00e1veis por mecanismos de mensageria comprovadamente s\u00f3lidos e est\u00e1veis.<\/p>\n<p>A abordagem mais simples \u00e9 utilizar filas\u00a0<em>p<\/em><i>oint-to-point. <\/i>Uma\u00a0alternativa mais sofisticada (e menos acoplada) \u00e9 a ado\u00e7\u00e3o de \u00a0<em>pub\/sub<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2634 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/async.png\" alt=\"\" width=\"588\" height=\"224\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/async.png 1070w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/async-300x114.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/async-1024x390.png 1024w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/async-768x293.png 768w\" sizes=\"(max-width: 588px) 100vw, 588px\" \/><\/p>\n<p>A alternativa tradicional \u00e9 utilizar estrat\u00e9gias de alta-disponibilidade com replica\u00e7\u00f5es e <em>load balancers.<\/em><\/p>\n<h4>Adotar <em>Bulkheads<\/em><\/h4>\n<p>Considere um sistema com tr\u00eas componentes: \u201cA\u201d, \u201cB\u201d e \u201cC\u201d. Onde \u201cA\u201d e \u201cB\u201d dependem sincronamente de \u201cC\u201d para funcionar.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2325 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/a.png\" alt=\"\" width=\"250\" height=\"230\" \/><\/p>\n<p>Caso \u201cC\u201d fique inst\u00e1vel, \u201cA\u201d e \u201cB\u201d podem ter dificuldades para continuar funcionando bem, o que pode espalhar falhas em \u201cefeito domin\u00f3\u201d. Ou seja, a instabilidade de \u201cC\u201d pode acabar gerando instabilidades em \u201cA\u201d e \u201cB\u201d que, eventualmente, ir\u00e3o causar instabilidades em outros componentes.<\/p>\n<hr \/>\n<strong>A maioria dos projetos de sistemas onde h\u00e1 depend\u00eancia forte entre componentes t\u00eam conting\u00eancia para falhas mais graves.<\/strong> No exemplo, provavelmente \u201cA\u201d e \u201cB\u201d est\u00e3o preparados para cen\u00e1rios onde \u201cC\u201d simplesmente pare de responder. <strong>Entretanto, poucas vezes encontramos arquiteturas preparadas para lidar com <em>response times <\/em>mais altos.<\/strong> Geralmente, lentid\u00e3o, mais do que indisponibilidade total, \u00e9 a causa raiz da maioria dos problemas mais cr\u00edticos em produ\u00e7\u00e3o.\n<hr \/>\n<p>Uma forma comum de tentar mitigar os impactos de instabilidades em um componente \u00e9 torn\u00e1-lo escal\u00e1vel na horizontal para, ent\u00e3o, levantar v\u00e1rias inst\u00e2ncias com demanda distribu\u00edda por um <em>load balancer.<\/em><\/p>\n<div class=\"wp-block-image\">\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2326 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/b.png\" alt=\"\" width=\"289\" height=\"292\" \/><\/p>\n<p>O problema, entretanto, \u00e9 que, com frequ\u00eancia, instabilidades, sobretudo de lentid\u00e3o, s\u00e3o ocasionadas por dificuldades de um componente para atender \u201crequisi\u00e7\u00f5es envenenadas\u201d provenientes de um \u201cofensor externo\u201d. Em nosso exemplo, caso \u201cA\u201d gere \u201crequisi\u00e7\u00f5es envenenadas\u201d para \u201cC\u201d, estas podem acabar afetando todas as inst\u00e2ncias do servi\u00e7o, mesmo escalados na horizontal, apenas retardando os efeitos ruins, sem evit\u00e1-los.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2327 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/c.png\" alt=\"\" width=\"289\" height=\"316\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/c.png 289w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/c-274x300.png 274w\" sizes=\"(max-width: 289px) 100vw, 289px\" \/><\/p>\n<\/div>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\">Uma alternativa eficiente para mitigar o risco dessa situa\u00e7\u00e3o \u00e9 compartimentar inst\u00e2ncias para as diversas origens de requisi\u00e7\u00e3o. Ou seja, \u201clevantar\u201d inst\u00e2ncias espec\u00edficas para cada natureza de solicita\u00e7\u00e3o, mantendo-as apartadas.<\/figure>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2328 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/d.png\" alt=\"\" width=\"289\" height=\"292\" \/><\/p>\n<\/div>\n<div class=\"wp-block-image\">\n<p>Dessa forma, a \u201cpress\u00e3o\u201d de \u201cA\u201d sobre \u201cC\u201d n\u00e3o impactar\u00e1 \u201cB\u201d. Nesse mesmo racioc\u00ednio, a \u201cpress\u00e3o\u201d de \u201cB\u201d sobre \u201cC\u201d tamb\u00e9m n\u00e3o causar\u00e1 problemas para \u201cA\u201d.<\/p>\n<\/div>\nNo \u201cmundo real\u201d, j\u00e1 vimos essa solu\u00e7\u00e3o ser aplicada, por exemplo, em grandes varejistas para apartar o tratamento de requisi\u00e7\u00f5es de aplica\u00e7\u00f5es m\u00f3veis, <em>site, <\/em>rob\u00f4s de compara\u00e7\u00e3o de pre\u00e7os e o Google (como voc\u00ea pode imaginar, para um varejista, \u00e9 tremendamente prejudicial ser \u201cpenalizado\u201d pelo gigante das buscas).\n<hr \/>\n<p>O nome dessa t\u00e9cnica de <em>design<\/em> \u00e9 <em>bulkhead, <\/em>em alus\u00e3o a forma como navios eram projetados para impedir que danos em uma parte do cascos causassem um naufr\u00e1gio.<\/p>\n<em>Bulkheads <\/em>obviamente, introduzem ociosidade desnecess\u00e1ria (leia-se desperd\u00edcio) de recursos a uma arquitetura, tornando-a economicamente menos interessante. Entretanto, essa inefici\u00eancia pode ser necess\u00e1ria e, geralmente, \u00e9 mais do que compensada com a minimiza\u00e7\u00e3o e isolamento de <em>downtimes. <\/em>Um de seus principais atrativos \u00e9 que pode ser adotada, frequentemente, com poucas altera\u00e7\u00f5es (ou at\u00e9 nenhuma) de c\u00f3digo.\n<h4>Suportar<em> Back pressure<\/em><\/h4>\n<p>Sempre o <em>traffic intensity\u00a0<\/em>for desfavor\u00e1vel para um componente, o ideal \u00e9 que este passe a recusar novas demandas (usando <em>load shedding <\/em>ou\u00a0<em>rate limiting<\/em>)<em>,<\/em> devolvendo a &#8220;press\u00e3o&#8221; para o cliente que dever\u00e1 implementar alguma estrat\u00e9gia de retentivas ou, at\u00e9 mesmo, reduzir o volume de demandas com alguma estrat\u00e9gia de\u00a0<em>gracefully degradation.<\/em><\/p>\n<p>Do ponto de vista do componente que est\u00e1 adotando\u00a0<em>back pressure,\u00a0<\/em>a implementa\u00e7\u00e3o \u00e9 restrita a algum mecanismo de sinaliza\u00e7\u00e3o (talvez retornando 429 &#8211; <em>Too many requests<\/em>) para o cliente indicando a condi\u00e7\u00e3o. Caber\u00e1 ao cliente adotar estrat\u00e9gia apropriada, conforme sinaliza\u00e7\u00e3o.<\/p>\n<h4>Suportar<em> Load shedding (Governor pattern)<\/em><\/h4>\n<p>Assim como um <em>rate limiter,\u00a0<\/em>um componente de\u00a0<em>load shedding\u00a0<\/em>opera como um <em>middleware\u00a0<\/em>que monitora os recursos computacionais necess\u00e1rios para um componente, bem como das depend\u00eancias, e recusa ativamente novas requisi\u00e7\u00f5es at\u00e9 que n\u00edveis saud\u00e1veis sejam restaurados.<\/p>\n<h4>Determinar<em> Timeouts\u00a0<\/em><\/h4>\n<p><strong>Pior do que componentes que param de responder s\u00e3o aqueles que passam a operar com lentid\u00e3o incomum.<\/strong>\u00a0Estabelecer <em>timeouts<\/em>\u00a0\u00e9 importante para impedir que componentes clientes esperem &#8220;tempo demais&#8221;, seja para solicita\u00e7\u00f5es s\u00edncronas quanto ass\u00edncronas.<\/p>\n<hr \/>\n<p>Embora n\u00e3o haja uma &#8220;receita de bolo&#8221; para escolher um <em>timeout<\/em> correto, eles devem ser relativamente curtos. A recomenda\u00e7\u00e3o segura \u00e9 150% do tempo m\u00e9dio de resposta do servi\u00e7o.<\/p>\n<h4>Adotar <em>proxies<\/em> para componentes que n\u00e3o est\u00e3o sob controle<\/h4>\n<p>Todo componente que n\u00e3o est\u00e1 sob controle do time de desenvolvimento interno e que precisa estar em conformidade com as t\u00e1ticas de resili\u00eancia, deve estar &#8220;envelopada&#8221; por um <em>proxy<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2705 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/proxy.png\" alt=\"\" width=\"412\" height=\"109\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/proxy.png 816w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/proxy-300x79.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/proxy-768x203.png 768w\" sizes=\"(max-width: 412px) 100vw, 412px\" \/><\/p>\n<p>O <em>proxy <\/em>(Envoy, PgBound, HAProxy, etc) consegue resolver regras como\u00a0<em>load shedding,<\/em>\u00a0<em>time outs<\/em>, entre outros.<\/p>\n<h4>Adotar o padr\u00e3o<em> Transaction Outbox<\/em><\/h4>\n<p>Comandos &#8211; requisi\u00e7\u00f5es que modificam o estado do servidor &#8211; demandam, atomicamente, atualiza\u00e7\u00f5es em bancos de dados e envio de mensagens (via algum mecanismo de mensageria).<\/p>\n<p>Em termos simples, em uma transa\u00e7\u00e3o, quando um\u00a0<em>commit\u00a0<\/em>acontece, mensagens devem ser enviadas. Entretanto, se for necess\u00e1rio um\u00a0<em>rollback<\/em>,<\/p>\n<p>A sa\u00edda simples \u00e9 adicionar uma tabela adicional, no banco de dados onde as transa\u00e7\u00f5es est\u00e3o sendo processadas, para &#8220;registrar&#8221; a demanda do envio de uma mensagem. Ao executar uma transa\u00e7\u00e3o, essa tabela deve receber, tamb\u00e9m uma inclus\u00e3o. Outro agente fica respons\u00e1vel por &#8220;ler a tabela&#8221; e efetivar o envio de mensagens.<\/p>\n<h4>Implantar<em> Circuit breakers<\/em><\/h4>\n<p><em>Circuit breaker<\/em> \u00e9 uma inst\u00e2ncia de m\u00e1quina de estados implementada entre dois componentes, um &#8220;cliente&#8221; e o outro &#8220;servidor&#8221;. O objetivo de um\u00a0<i>Circuit breaker\u00a0<\/i>\u00e9 proteger o &#8220;servidor&#8221; de requisi\u00e7\u00f5es enquanto este estiver enfrentando dificuldades (potencial satura\u00e7\u00e3o).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2639 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/circuitbreaker-1.png\" alt=\"\" width=\"606\" height=\"431\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/circuitbreaker-1.png 1270w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/circuitbreaker-1-300x213.png 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/circuitbreaker-1-1024x727.png 1024w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/07\/circuitbreaker-1-768x545.png 768w\" sizes=\"(max-width: 606px) 100vw, 606px\" \/><\/p>\n<p>O funcionamento da m\u00e1quina de estados \u00e9 a seguinte:<\/p>\n<ol>\n<li>Circuito fechado\n<ul>\n<li>Toda requisi\u00e7\u00e3o do &#8220;cliente&#8221; deve ser encaminhada ao &#8220;servidor&#8221;<\/li>\n<li>Se houverem mais falhas do que o &#8220;aceit\u00e1vel&#8221; dentro de um intervalo de tempo, ent\u00e3o o circuito deve &#8220;abrir&#8221;.<\/li>\n<\/ul>\n<\/li>\n<li>Circuito aberto\n<ul>\n<li>Nenhuma requisi\u00e7\u00e3o do &#8220;cliente&#8221; deve ser encaminhada ao &#8220;servidor&#8221;, falhando imediatamente<\/li>\n<li>Transcorrido um determinado tempo, o circuito deve ficar &#8220;meio aberto&#8221;<\/li>\n<\/ul>\n<\/li>\n<li>Circuito meio aberto\n<ol>\n<li>Algumas requisi\u00e7\u00f5es devem ser encaminhadas para o &#8220;servidor&#8221;, \u00a0outras negadas<\/li>\n<li>Se as falhas persistirem, o circuito dever\u00e1 &#8220;abrir&#8221; novamente<\/li>\n<li>Se as falhas n\u00e3o ocorrerem mais, o circuito dever\u00e1 &#8220;fechar&#8221;.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2>\/\/ TODO<\/h2>\n<p>Antes de avan\u00e7ar para o pr\u00f3ximo cap\u00edtulo, recomendo as seguintes reflex\u00f5es:<\/p>\n<ol>\n<li>Que padr\u00f5es para resili\u00eancia j\u00e1 adotou?<\/li>\n<li>Qual a rela\u00e7\u00e3o entre a complexidade crescente dos sistemas e a demanda por resili\u00eancia?<\/li>\n<\/ol>\n","protected":false},"featured_media":3829,"parent":0,"comment_status":"open","ping_status":"closed","template":"","url":[72],"sessoes":[58],"apendices":[],"capitulos":[41],"class_list":["post-4355","volume-1","type-volume-1","status-publish","has-post-thumbnail","hentry","url-permanente","sessoes-secao-2","capitulos-capitulo-2-4"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software<\/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:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software\" \/>\n<meta property=\"og:description\" content=\"Software \u00e9 cada vez mais importante. Hoje em dia, \u00e9 dif\u00edcil imaginar qualquer atividade relevante, dentro e fora das organiza\u00e7\u00f5es, que n\u00e3o seja suportada direta ou indiretamente por software. Quando software n\u00e3o funciona a produtividade \u00e9 prejudicada.\u00a0Muitas vezes, o trabalho \u00e9 interrompido e resultados deixam de ser atingidos. Em cen\u00e1rios extremos, software que n\u00e3o funciona [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/\" \/>\n<meta property=\"og:site_name\" content=\"Manual do Arquiteto de Software\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/eximiaco\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-12T21:05:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"338\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@eximiaco\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"18 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/\",\"name\":\"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software\",\"isPartOf\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg\",\"datePublished\":\"2022-07-03T20:15:30+00:00\",\"dateModified\":\"2024-01-12T21:05:22+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg\",\"width\":600,\"height\":338},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Volume 1\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"name\":\"Manual do Arquiteto de Software\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\",\"name\":\"EximiaCo\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"width\":150,\"height\":150,\"caption\":\"EximiaCo\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/eximiaco\",\"https:\/\/x.com\/eximiaco\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software","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:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/","og_locale":"pt_BR","og_type":"article","og_title":"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software","og_description":"Software \u00e9 cada vez mais importante. Hoje em dia, \u00e9 dif\u00edcil imaginar qualquer atividade relevante, dentro e fora das organiza\u00e7\u00f5es, que n\u00e3o seja suportada direta ou indiretamente por software. Quando software n\u00e3o funciona a produtividade \u00e9 prejudicada.\u00a0Muitas vezes, o trabalho \u00e9 interrompido e resultados deixam de ser atingidos. Em cen\u00e1rios extremos, software que n\u00e3o funciona [&hellip;]","og_url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/","og_site_name":"Manual do Arquiteto de Software","article_publisher":"https:\/\/facebook.com\/eximiaco","article_modified_time":"2024-01-12T21:05:22+00:00","og_image":[{"width":600,"height":338,"url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@eximiaco","twitter_misc":{"Est. tempo de leitura":"18 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/","name":"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes - Manual do Arquiteto de Software","isPartOf":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website"},"primaryImageOfPage":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage"},"thumbnailUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg","datePublished":"2022-07-03T20:15:30+00:00","dateModified":"2024-01-12T21:05:22+00:00","breadcrumb":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#primaryimage","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.4.jpg","width":600,"height":338},{"@type":"BreadcrumbList","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquiteturas-de-sistemas-resilientes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/"},{"@type":"ListItem","position":2,"name":"Volume 1","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/"},{"@type":"ListItem","position":3,"name":"Cap 2.4 Fundamentos para arquiteturas de sistemas resilientes"}]},{"@type":"WebSite","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","name":"Manual do Arquiteto de Software","description":"","publisher":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization","name":"EximiaCo","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","width":150,"height":150,"caption":"EximiaCo"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/eximiaco","https:\/\/x.com\/eximiaco"]}]}},"_links":{"self":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1\/4355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1"}],"about":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/types\/volume-1"}],"replies":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/comments?post=4355"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media\/3829"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media?parent=4355"}],"wp:term":[{"taxonomy":"url","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/url?post=4355"},{"taxonomy":"sessoes","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/sessoes?post=4355"},{"taxonomy":"apendices","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/apendices?post=4355"},{"taxonomy":"capitulos","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/capitulos?post=4355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}