Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Bloqueie temporariamente o acesso a um serviço ou recurso remoto após falhas atingirem um limite, em vez de repetir repetidamente uma operação que provavelmente falhará. Essa abordagem lida com falhas que levam diferentes períodos de tempo para se recuperar, permite que o serviço com falha se recupere e melhora a estabilidade e a resiliência de um aplicativo.
Contexto e problema
Em um ambiente distribuído, as chamadas para recursos e serviços remotos podem falhar devido a falhas transitórias. Falhas transitórias incluem recursos excessivamente comprometidos ou temporariamente indisponíveis, conexões de rede lentas ou tempos limite. Essas falhas normalmente se corrigem após um curto período de tempo. Para ajudar a gerenciar essas falhas, você deve criar um aplicativo de nuvem para usar uma estratégia, como o padrão de repetição.
Eventos imprevistos podem criar falhas que levam mais tempo para serem corrigidas. Essas falhas podem variar em gravidade, desde uma perda parcial de conectividade até uma falha de serviço completa. Nessas situações, um aplicativo não deve repetir continuamente uma operação que é improvável de ter êxito. Em vez disso, o aplicativo deve reconhecer rapidamente a operação com falha e lidar com a falha adequadamente.
Se um serviço estiver ocupado, a falha em uma parte do sistema poderá levar a falhas em cascata. Por exemplo, você pode configurar uma operação que invoca um serviço para implementar um tempo limite. Se o serviço não responder dentro desse período, a operação responderá com uma mensagem de falha.
No entanto, essa estratégia pode bloquear solicitações simultâneas para a mesma operação até que o período de tempo limite expire. Essas solicitações bloqueadas podem conter recursos críticos do sistema, como memória, threads e conexões de banco de dados. Esse problema pode esgotar recursos, o que pode falhar em outras partes não relacionadas do sistema que precisam usar os mesmos recursos.
Nessas situações, uma operação deve falhar imediatamente e apenas tentar invocar o serviço se for provável que ela tenha êxito. Para resolver esse problema, defina um tempo limite mais curto. Mas verifique se o tempo limite é longo o suficiente para que a operação seja bem-sucedida na maior parte do tempo.
Solução
O padrão disjuntor ajuda a impedir que um aplicativo tente executar repetidamente uma operação que provavelmente falhará. Esse padrão permite que o aplicativo continue em execução sem esperar que a falha seja corrigida ou desperdiçando ciclos de CPU ao determinar que a falha é persistente. O padrão disjuntor também permite que um aplicativo detecte quando a falha é resolvida. Se a falha for resolvida, o aplicativo poderá tentar invocar a operação novamente.
Observação
O Padrão Circuit Breaker serve a uma finalidade diferente do Padrão Retry. O padrão de repetição permite que um aplicativo repita uma operação com a expectativa de que ele eventualmente tenha êxito. O padrão disjuntor impede que um aplicativo execute uma operação que provavelmente falhará. Um aplicativo pode combinar esses dois padrões usando o padrão de Repetição para invocar uma operação por meio de um disjuntor. No entanto, a lógica de repetição deverá ser sensível às exceções retornadas pelo disjuntor e parar as novas tentativas se o disjuntor indicar que uma falha não é transitória.
Um disjuntor atua como um proxy para operações que podem falhar. O proxy deve monitorar o número de falhas recentes e usar essas informações para decidir se deseja permitir que a operação prossiga ou retorne uma exceção imediatamente.
Você pode implementar o proxy como um computador de estado que inclui os estados a seguir. Esses estados imitam a funcionalidade de um disjuntor elétrico:
Fechado: a solicitação do aplicativo é encaminhada para a operação. O proxy mantém uma contagem do número de falhas recentes. Se a chamada para a operação não for bem-sucedida, o proxy incrementará essa contagem. Se o número de falhas recentes exceder um limite especificado em um determinado período de tempo, o proxy será colocado no estado Open e iniciará um temporizador de tempo limite. Quando o temporizador expira, o proxy é colocado no estado Half-Open .
Observação
Durante o tempo limite, o sistema tenta corrigir o problema que causou a falha antes de permitir que o aplicativo tente a operação novamente.
Abrir: A solicitação do aplicativo falha imediatamente e uma exceção é retornada ao aplicativo.
Entreaberto: um número limitado de solicitações do aplicativo pode ser passado e invocar a operação. Se essas solicitações forem bem-sucedidas, o disjuntor assumirá que a falha que causou a falha foi corrigida e o disjuntor alterna para o estado Fechado . O contador de falhas é reiniciado. Se qualquer solicitação falhar, o disjuntor assumirá que a falha ainda está presente, portanto, ela será revertida para o estado Abrir . Ele recomeça o cronômetro de tempo limite para que o sistema possa se recuperar da falha.
Observação
O estado Half-Open ajuda a impedir que um serviço de recuperação seja subitamente inundado com solicitações. À medida que um serviço se recupera, ele pode ser capaz de dar suporte a um volume limitado de solicitações até que a recuperação seja concluída. Mas enquanto a recuperação está em andamento, uma enxurrada de trabalho pode fazer com que o serviço expire ou falhe novamente.
O diagrama a seguir mostra as operações do contador para cada estado.
O contador de falha do estado Fechado é baseado em tempo. Ele é reiniciado automaticamente em intervalos periódicos. Esse design ajuda a impedir que o disjuntor entre no estado Abrir se ele tiver falhas ocasionais. O limite de falha dispara o estado Abrir somente quando um número especificado de falhas ocorre durante um intervalo especificado.
O contador de êxito para o estado Half-Open registra o número de tentativas bem-sucedidas de invocar a operação. O disjuntor é revertido para o estado Fechado após um número especificado de invocações de operação consecutivas bem-sucedidas. Se qualquer invocação falhar, o disjuntor entrará no estado Abrir imediatamente e o contador de êxito será redefinido na próxima vez que ele entrar no estado de Meio Aberto .
Observação
A recuperação do sistema é baseada em operações externas, como restaurar ou reiniciar um componente com falha ou reparar uma conexão de rede.
O padrão de disjuntor fornece estabilidade enquanto o sistema se recupera de uma falha e minimiza o impacto no desempenho. Ele pode ajudar a manter o tempo de resposta do sistema. Esse padrão rejeita rapidamente uma solicitação de uma operação que provavelmente falhará, em vez de aguardar o tempo limite da operação ou nunca retornar. Se o disjuntor gerar um evento sempre que mudar de estado, essas informações poderão ajudar a monitorar a integridade do componente do sistema protegido ou alertar um administrador quando um disjuntor mudar para o estado Aberto.
Você pode personalizar e adaptar esse padrão a diferentes tipos de falhas. Por exemplo, você pode aplicar um temporizador de tempo limite crescente para um disjuntor. Você pode colocar o disjuntor no estado Aberto por alguns segundos inicialmente. Se a falha não for resolvida, aumente o tempo limite para alguns minutos e ajuste adequadamente. Em alguns casos, em vez de retornar uma falha e gerar uma exceção, o estado Abrir pode retornar um valor padrão que seja significativo para o aplicativo.
Observação
Tradicionalmente, os disjuntores dependiam de limites pré-configurados, como contagem de falhas e duração do tempo limite. Essa abordagem resultou em um comportamento determinístico, mas às vezes abaixo do ideal.
Técnicas adaptáveis que usam IA e machine learning podem ajustar dinamicamente limites com base em padrões de tráfego em tempo real, anomalias e taxas de falha histórica. Essa abordagem melhora a resiliência e a eficiência.
Problemas e considerações
Considere os seguintes fatores ao implementar esse padrão:
Tratamento de exceção: Um aplicativo que invoca uma operação por meio de um disjuntor deve ser capaz de lidar com as exceções se a operação não estiver disponível. O gerenciamento de exceções é baseado no aplicativo. Por exemplo, um aplicativo pode degradar temporariamente sua funcionalidade, invocar uma operação alternativa para tentar executar a mesma tarefa ou obter os mesmos dados ou relatar a exceção ao usuário e solicitar que ele tente novamente mais tarde.
Tipos de exceções: Os motivos de uma falha de solicitação podem variar em gravidade. Por exemplo, uma solicitação pode falhar porque um serviço remoto falha e requer vários minutos para ser recuperado ou porque um serviço sobrecarregado causa um tempo limite. Um disjuntor pode ser capaz de examinar os tipos de exceções que ocorrem e ajustar sua estratégia com base na natureza dessas exceções. Por exemplo, pode exigir um número maior de exceções de tempo limite para disparar o disjuntor para o estado Abrir em comparação com o número de falhas causadas pelo serviço indisponível.
Monitorização: Um disjuntor deve fornecer uma observabilidade clara em solicitações com falha e bem-sucedidas para que as equipes de operações possam avaliar a integridade do sistema. Use o rastreamento distribuído para visibilidade de ponta a ponta entre serviços.
Recuperabilidade: Você deve configurar o disjuntor para alinhar-se ao padrão de recuperação provável da operação que ele protege. Por exemplo, se o disjuntor permanecer no estado Aberto por um longo período, ele poderá gerar exceções mesmo se o motivo da falha for resolvido. De forma semelhante, um disjuntor pode flutuar e reduzir os tempos de resposta dos aplicativos se mudar do estado Aberto para o estado Entreaberto muito rapidamente.
Teste de operações com falha: No estado Abrir , em vez de usar um temporizador para determinar quando alternar para o estado de Meia-Abertura , um disjuntor pode executar ping periodicamente no serviço ou recurso remoto para determinar se ele está disponível. Esse ping pode tentar invocar uma operação com falha anterior ou usar uma operação especial de verificação de integridade fornecida pelo serviço remoto. Para obter mais informações, consulte Padrão de monitoramento de ponto de extremidade de integridade.
Substituição manual: se o tempo de recuperação de uma operação com falha for extremamente variável, forneça uma opção de reinício manual que permita ao administrador fechar um disjuntor e reiniciar o contador de falhas. Da mesma forma, um administrador pode forçar um disjuntor para o estado Aberto e reiniciar o tempo limite se a operação protegida estiver temporariamente indisponível.
Simultaneidade: Um grande número de instâncias simultâneas de um aplicativo pode acessar o mesmo disjuntor. A implementação não deve bloquear solicitações simultâneas nem adicionar uma sobrecarga excessiva a cada chamada a uma operação.
Diferenciação de recursos: Tenha cuidado ao usar um único disjuntor para um tipo de recurso se houver vários provedores independentes subjacentes. Por exemplo, em um repositório de dados que contém vários fragmentos, um fragmento pode estar totalmente acessível enquanto outro enfrenta um problema temporário. Se as respostas de erro nesses cenários forem mescladas, um aplicativo poderá tentar acessar alguns fragmentos mesmo quando a falha for provável. E o acesso a outros fragmentos pode ser bloqueado, mesmo que a chance de êxito seja alta.
Disjuntor acelerado: às vezes, uma resposta de falha pode conter informações suficientes para que o disjuntor seja acionado imediatamente e permaneça assim por uma quantidade mínima de tempo. Por exemplo, a resposta de erro de um recurso compartilhado sobrecarregado pode indicar que o aplicativo deve tentar novamente em alguns minutos, em vez de tentar novamente imediatamente.
Implantações de várias regiões: Você pode criar um disjuntor para implantações de região única ou de várias regiões. Para projetar implantações de várias regiões, use balanceadores de carga globais ou estratégias personalizadas de quebra de circuito com reconhecimento de região que ajudam a garantir failover controlado, otimização de latência e conformidade regulatória.
Disjuntores de malha de serviço: Você pode implementar disjuntores na camada de aplicação ou como um recurso transversal e abstrato. Por exemplo, as malhas de serviço geralmente oferecem interrupção de circuito como um sidecar ou como uma funcionalidade autônoma, sem modificar o código do aplicativo.
Observação
Um serviço poderá retornar HTTP 429 (muitas solicitações) se estiver limitando o cliente ou HTTP 503 (serviço indisponível) se o serviço não estiver disponível. A resposta pode incluir outras informações, como a duração prevista do atraso.
Reprodução da solicitação com falha: no estado Aberto, em vez de falhar imediatamente, um disjuntor pode registrar os detalhes de cada solicitação em um diário e organizar essas solicitações para serem reproduzidas quando o serviço ou o recurso estiver disponível.
Tempos limite inadequados em serviços externos: um disjuntor pode não proteger totalmente os aplicativos contra falhas em serviços externos que têm longos períodos de tempo limite. Se o tempo limite for muito longo, um thread executando um disjuntor poderá ser bloqueado por um longo período antes de o disjuntor indicar a falha na operação. Durante esse momento, muitas outras instâncias do aplicativo também poderão tentar invocar o serviço por meio do disjuntor e associar vários threads antes que todos falhem.
Adaptabilidade à diversificação de computação: Os disjuntores devem considerar diferentes ambientes de computação, desde cargas de trabalho sem servidor até cargas de trabalho em contêineres, em que fatores como inícios a frio e escalabilidade afetam o tratamento de falhas. Abordagens adaptáveis podem ajustar dinamicamente estratégias com base no tipo de computação, o que ajuda a garantir a resiliência entre arquiteturas heterogêneas.
Quando usar esse padrão
Use esse padrão quando:
Você deseja evitar falhas em cascata interrompendo chamadas de serviço remoto excessivas ou solicitações de acesso a um recurso compartilhado se essas operações provavelmente falharem.
Você deseja rotear o tráfego de forma inteligente com base em sinais de falha em tempo real para aprimorar a resiliência de várias regiões.
Você deseja proteger contra dependências lentas para que você possa manter seus objetivos de nível de serviço e evitar degradação de desempenho de serviços de alta latência.
Você deseja gerenciar problemas de conectividade intermitente e reduzir falhas de solicitação em ambientes distribuídos.
O padrão pode não ser adequado nestes casos:
Você precisa gerenciar o acesso a recursos privados locais em um aplicativo, como estruturas de dados na memória. Nesse ambiente, um disjuntor adiciona sobrecarga ao seu sistema.
Você precisa usá-lo como um substituto para lidar com exceções na lógica de negócios de seus aplicativos.
Algoritmos de repetição conhecidos são suficientes e suas dependências são projetadas para lidar com mecanismos de repetição. Nesse cenário, um disjuntor em seu aplicativo pode adicionar complexidade desnecessária ao seu sistema.
Esperar que um disjuntor seja redefinido pode introduzir atrasos inaceitáveis.
Você tem uma arquitetura orientada por mensagens ou por eventos, pois elas geralmente roteiam mensagens com falha para uma fila de mensagens mortas para processamento manual ou adiado. Mecanismos internos de isolamento e repetição de falhas geralmente são suficientes.
A recuperação de falha é gerenciada no nível da infraestrutura ou da plataforma, como com verificações de integridade em balanceadores de carga globais ou malhas de serviço.
Design de carga de trabalho
Avalie como usar o padrão Circuit Breaker no design de uma arquitetura de carga de trabalho para atender às metas e princípios abordados nos pilares do Azure Well-Architected Framework. A tabela a seguir fornece diretrizes sobre como esse padrão dá suporte às metas de cada pilar.
| Pilar | Como esse padrão apoia os objetivos do pilar |
|---|---|
| As decisões de design de confiabilidade ajudam sua carga de trabalho a se tornar resiliente ao mau funcionamento e garantir que ela se recupere para um estado totalmente funcional após a ocorrência de uma falha. | Esse padrão ajuda a impedir que uma dependência com falha sobrecarregue. Use este padrão para acionar degradação suave na carga de trabalho. Acople disjuntores à recuperação automática para fornecer autopreservação e autorrecuperação. - RE:03 Análise do modo de falha - Falhas transitórias - RE:07 Autopreservação |
| A Eficiência de Desempenho ajuda sua carga de trabalho a atender com eficiência às demandas por meio de otimizações no dimensionamento, nos dados e no código. | Esse padrão evita a abordagem de tentar novamente em caso de erro, que pode levar ao uso excessivo de recursos durante a recuperação de uma dependência e pode sobrecarregar o desempenho em uma dependência que está tentando passar por recuperação. - PE:07 Código e infraestrutura - PE:11 Respostas a problemas em tempo real |
Se esse padrão introduzir compensações dentro de um pilar, considere-as em relação aos objetivos dos outros pilares.
Exemplo
Este exemplo implementa o padrão de disjuntor para ajudar a evitar o excesso de cota usando a camada gratuita vitalícia do Azure Cosmos DB. Essa camada é principalmente para dados não críticos e opera sob um plano de capacidade que aloca uma cota específica de unidades de recursos por segundo. durante eventos sazonais, a demanda pode exceder a capacidade fornecida, o que pode resultar em respostas 429.
Quando ocorrem picos de demanda, os alertas do Azure Monitor com limites dinâmicos detectam e notificam proativamente as operações e as equipes de gerenciamento de que o banco de dados requer mais capacidade. Simultaneamente, um disjuntor ajustado usando padrões de erro históricos é usado para evitar falhas em cascata. Nesse estado, o aplicativo se degrada de forma controlada, retornando respostas padrão ou em cache. O aplicativo informa aos usuários sobre a indisponibilidade temporária de determinados dados, preservando a estabilidade geral do sistema.
Essa estratégia aprimora a resiliência que se alinha à justificativa empresarial. Ele controla os aumentos de capacidade para que as equipes de carga de trabalho possam gerenciar aumentos de custos deliberadamente e manter a qualidade do serviço sem aumentar inesperadamente as despesas operacionais. Depois que a demanda diminuir ou a maior capacidade for confirmada, o disjuntor é reiniciado e o aplicativo retornará à funcionalidade completa que se alinha aos objetivos técnicos e orçamentários.
Baixe um arquivo do Visio dessa arquitetura.
Fluxo A: estado fechado
O sistema opera normalmente e todas as solicitações chegam ao banco de dados sem retornar respostas
429HTTP.O disjuntor permanece fechado e nenhuma resposta padrão ou armazenada em cache é necessária.
Fluxo B: Estado aberto
Quando o disjuntor recebe a primeira
429resposta, ele viaja para um estado Open .As solicitações subsequentes são imediatamente interrompidas, o que retorna respostas padrões ou em cache e informa os usuários da degradação temporária. O aplicativo é protegido contra sobrecarga adicional.
O Azure Monitor recebe logs e dados de telemetria e os avalia em relação aos limites dinâmicos. Um alerta é disparado se as condições da regra de alerta forem atendidas.
Um grupo de ações notifica proativamente a equipe de operações da condição de sobrecarga.
Após a aprovação da equipe de carga de trabalho, a equipe de operações poderá aumentar a taxa de transferência provisionada para aliviar a sobrecarga ou atrasar o dimensionamento, caso a carga diminua naturalmente.
Fluxo C: estado entreaberto
Após um tempo limite predefinido, o disjuntor entra em um estado de Meio Aberto que permite um número limitado de solicitações de avaliação.
Se essas solicitações de avaliação
429forem bem-sucedidas sem retornar respostas, o disjuntor será redefinido para um estado Fechado e as operações normais voltarão ao Fluxo A. Se as falhas persistirem, o disjuntor será revertido para o estado Aberto ou o Fluxo B.
Componentes
O Serviço de Aplicativo do Azure hospeda o aplicativo Web que serve como o ponto de entrada principal para solicitações de cliente. O código do aplicativo implementa a lógica que impõe políticas de disjuntor e fornece respostas padrão ou armazenadas em cache quando o circuito está aberto. Essa arquitetura ajuda a evitar sobrecarga em sistemas downstream e manter a experiência do usuário durante o pico de demanda ou falhas.
Azure Cosmos DB é um dos repositórios de dados do aplicativo. Ele fornece dados não críticos por meio da camada gratuita, que é ideal para pequenas cargas de trabalho de produção. O mecanismo de disjuntor ajuda a limitar o tráfego para o banco de dados durante períodos de alta demanda.
O Azure Monitor funciona como a solução de monitoramento centralizada. Ele agrega todos os logs de atividades para ajudar a garantir uma observabilidade abrangente de ponta a ponta. O Azure Monitor recebe logs e dados de telemetria do Serviço de Aplicativo e das principais métricas do Azure Cosmos DB (como o número de
429respostas) para agregação e análise.Os alertas do Azure Monitor comparam as regras de alerta com limiares dinâmicos para identificar possíveis interrupções com base em dados históricos. Alertas predefinidos notificam a equipe de operações quando os limites são violados.
Às vezes, a equipe de carga de trabalho pode aprovar um aumento na taxa de transferência provisionada, mas a equipe de operações prevê que o sistema pode se recuperar por conta própria porque a carga não é muito alta. Nesses casos, o tempo limite do disjuntor expira naturalmente. Durante esse tempo, se as respostas
429cessarem, o cálculo de limite detectará as interrupções prolongadas e as excluirá do algoritmo de aprendizado. Como resultado, na próxima vez que ocorrer uma sobrecarga, o limite aguardará uma taxa de erro mais alta no Azure Cosmos DB, o que atrasa a notificação. Esse ajuste permite que o disjuntor lide com o problema sem um alerta imediato, o que melhora o custo e a eficiência operacional.
Recursos relacionados
O padrão de repetição descreve como um aplicativo pode lidar com falhas temporárias previstas quando tenta se conectar a um serviço ou recurso de rede repetindo de forma transparente uma operação que falhou anteriormente.
O Padrão de Monitoramento de Integridade no Ponto de Extremidade descreve como um disjuntor pode testar a integridade de um serviço enviando uma solicitação para um ponto de extremidade que o serviço expõe. O serviço deve retornar informações que indiquem seu status.