Recomendações para projetar para simplicidade e eficiência

Aplica-se a esta recomendação da lista de verificação de confiabilidade do Azure Well-Architected Framework:

RE:01 Projete sua carga de trabalho para se alinhar aos objetivos de negócios e evitar complexidade ou sobrecarga desnecessárias. Use uma abordagem prática e equilibrada para tomar decisões de design que forneçam os resultados desejados. Contenha seu projeto às necessidades para reduzir ineficiências e problemas potenciais.

Este guia descreve as recomendações para minimizar a complexidade e a sobrecarga desnecessárias para manter suas cargas de trabalho simples e eficientes. Escolha os melhores componentes para executar as tarefas de carga de trabalho necessárias para otimizar a confiabilidade de sua carga de trabalho. Para diminuir seus encargos de desenvolvimento e gerenciamento, aproveite as eficiências que os serviços fornecidos pela plataforma oferecem. Esse design ajuda você a criar uma arquitetura de carga de trabalho resiliente, repetível, escalonável e gerenciável.

Definições

Termo Definição
Carga de trabalho Um recurso discreto ou uma tarefa de computação que você pode separar logicamente de outras tarefas.

Principais estratégias de design

Um princípio fundamental do design para confiabilidade é manter as coisas simples e eficientes. Foque o design da sua carga de trabalho no atendimento aos requisitos de negócios para reduzir o risco de complexidade desnecessária ou excesso de sobrecarga. Considere as recomendações neste artigo para ajudá-lo a tomar decisões sobre seu design para criar uma carga de trabalho enxuta, eficiente e confiável. As cargas de trabalho diferentes podem ter diferentes requisitos de disponibilidade, escalabilidade, consistência de dados e recuperação de desastres.

Você deve justificar cada decisão de design com um requisito de negócios. Esse princípio de design pode parecer óbvio, mas é crucial para o design da carga de trabalho. Seu aplicativo oferece suporte a milhões de usuários ou a alguns milhares? Há grandes picos de tráfego ou uma carga de trabalho constante? Qual nível de interrupção de aplicativos é aceitável? Os requisitos de negócios orientam essas considerações de design.

Compensação: uma solução complexa pode oferecer mais recursos e flexibilidade, mas pode afetar a confiabilidade da carga de trabalho porque requer mais coordenação, comunicação e gerenciamento de componentes. Como alternativa, uma solução mais simples pode não atender totalmente às expectativas do usuário ou pode ter um efeito negativo na escalabilidade e extensibilidade à medida que a carga de trabalho evolui.

Colabore com as partes interessadas em exercícios de design

Trabalhar com as partes interessadas para:

  • Defina e atribua um nível de criticidade aos fluxos de usuário e fluxos do sistema da carga de trabalho. Concentre seu design em fluxos críticos para ajudá-lo a determinar os componentes necessários e a melhor abordagem para atingir o nível de resiliência necessário.

  • Defina requisitos funcionais e não funcionais. Considere os requisitos funcionais para determinar se um aplicativo executa uma tarefa. Considere os requisitos não funcionais para determinar o quão bem o aplicativo executa uma tarefa. Certifique-se de entender os requisitos não funcionais, como escalabilidade, disponibilidade e latência. Esses requisitos influenciam as decisões de design e opções de tecnologia.

  • Decomponha cargas de trabalho em componentes. Priorize a simplicidade, eficiência e confiabilidade em seu projeto. Determine os componentes necessários para dar suporte aos seus fluxos. Alguns componentes suportam vários fluxos. Identifique qual desafio um componente aborda conceitualmente e considere remover um componente de fluxos individuais para simplificar o design geral e, ao mesmo tempo, fornecer funcionalidade completa. Para obter mais informações, consulte Recomendações para executar uma análise de modos de falha.

  • Use a análise do modo de falha para identificar pontos únicos de falha e riscos potenciais. Considere se você precisa levar em conta situações improváveis, por exemplo, uma área geográfica que sofre um grande desastre natural que afeta todas as zonas de disponibilidade na região. É caro e envolve compensações significativas para mitigar esses riscos incomuns. Entenda claramente a tolerância da sua empresa ao risco. Para obter mais informações, consulte Recomendações para executar uma análise de modos de falha.

  • Defina metas de disponibilidade e recuperação para seus fluxos para informar a arquitetura da carga de trabalho. As métricas de negócios incluem SLOs (objetivos de nível de serviço), SLAs (contratos de nível de serviço), MTTR (tempo médio de recuperação), MTBF (tempo médio entre falhas), RTO (Recovery Time Objectives, objetivos de tempo de recuperação) e RPOs (Recovery Point Objectives, objetivos de ponto de recuperação). Defina valores de destino para essas métricas. Esse exercício pode exigir compromisso e compreensão mútua entre as equipes de tecnologia e negócios para garantir que as metas de cada equipe atendam aos objetivos de negócios e sejam realistas. Para saber mais, confira Recomendações para definir destinos de confiabilidade.

Prefira escolhas de design mais simples

Você pode executar as seguintes recomendações sem o envolvimento das partes interessadas:

  • Esforce-se pela simplicidade e clareza em seu design. Use o nível apropriado de abstração e granularidade para seus componentes e serviços. Evite a engenharia excessiva ou insuficiente de sua solução. Por exemplo, se você dividir seu código em várias funções pequenas, será difícil entender, testar e manter.

  • Admita que todos os aplicativos bem-sucedidos mudam com o tempo, seja para corrigir bugs, implementar novos recursos ou tecnologias ou tornar os sistemas existentes mais escaláveis e resilientes.

  • Use as opções de PaaS (plataforma como serviço) em vez de IaaS (infraestrutura como serviço) quando possível. O IaaS é como ter uma caixa de peças. Você pode criar qualquer coisa, mas deve montar por conta própria. As opções de PaaS são mais fáceis de configurar e de administrar. Você não precisa configurar VMs (máquinas virtuais) ou redes virtuais. Você também não precisa executar tarefas de manutenção, como instalar patches e atualizações.

  • Use mensagens assíncronas para desacoplar o produtor da mensagem do consumidor.

  • Infraestrutura abstrata distante da lógica do domínio. Verifique se a lógica de domínio não interfere na funcionalidade relacionada à infraestrutura, como mensagens ou persistência.

  • Descarregar preocupações abrangentes para um serviço separado. Minimize a necessidade de duplicar o código em diferentes funções, prefira reutilizar serviços com interfaces bem definidas que possam ser facilmente consumidas por diferentes componentes. Por exemplo, se vários serviços precisarem autenticar solicitações, você poderá mover essa funcionalidade para seu próprio serviço. Em seguida, você pode evoluir o serviço de autenticação. Por exemplo, você pode adicionar um novo fluxo de autenticação sem tocar em nenhum dos serviços que o utilizam.

  • Avalie a adequação de padrões e práticas comuns às suas necessidades. Evite seguir tendências ou recomendações que podem não ser as melhores para seu contexto ou requisitos. Por exemplo, os microsserviços não são a melhor opção para todos os aplicativos porque podem introduzir problemas de complexidade, sobrecarga e dependência.

Desenvolva código apenas o suficiente

Os princípios de simplicidade, eficiência e confiabilidade também se aplicam às suas práticas de desenvolvimento. Em uma carga de trabalho fracamente acoplada e dividida em componentes, determine a funcionalidade que um componente fornece. Desenvolva seus fluxos para aproveitar essa funcionalidade. Considere estas recomendações para suas práticas de desenvolvimento:

  • Use os recursos da plataforma quando eles atenderem aos seus requisitos de negócios. Por exemplo, para descarregar o desenvolvimento e o gerenciamento, use soluções low-code, no-code ou serverless que seu provedor de nuvem oferece.

  • Use bibliotecas e estruturas.

  • Introduza a programação em pares ou sessões dedicadas de revisão de código como uma prática de desenvolvimento.

  • Implemente uma abordagem para identificar código morto. Seja cético em relação ao código que seus testes automatizados não cobrem.

Selecione o armazenamento de dados certo

No passado, muitas organizações armazenavam todos os próprios dados em grandes bancos de dados SQL relacionais. Os bancos de dados relacionais fornecem garantias atômicas, consistentes, isoladas e duráveis (ACID) para transações de dados relacionais. Mas esses bancos de dados vêm com desvantagens:

  • As consultas podem exigir junções caras.

  • Você precisa normalizar os dados e reestruturá-los para o esquema ao gravar.

  • A contenção de bloqueio pode afetar o desempenho.

Alternativas a bancos de dados relacionais

Em uma solução grande, uma única tecnologia de armazenamento de dados provavelmente não atende a todas as suas necessidades. As alternativas aos bancos de dados relacionais incluem:

  • Repositórios de chave-valor

  • Bancos de dados de documentos

  • Bancos de dados de mecanismo de pesquisa

  • Bancos de dados de séries temporais

  • Bancos de dados de família de coluna

  • Bancos de dados de grafo

Cada opção tem prós e contras. Diferentes tipos de dados são mais adequados para diferentes tipos de armazenamento de dados. Escolha a tecnologia de armazenamento mais adequada aos seus dados e como usá-la.

Por exemplo, você pode armazenar um catálogo de produtos em um banco de dados de documentos, como o Azure Cosmos DB, que dá suporte a um esquema flexível. Cada descrição do produto é um documento independente. Para consultas em todo o catálogo, você pode indexar o catálogo e armazenar o índice no Azure Cognitive Search. O inventário de produtos pode ir para um banco de dados SQL porque esses dados exigem garantias ACID.

Recomendações

  • Considere outros armazenamentos de dados. Bancos de dados relacionais nem sempre são apropriados. Para obter mais informações, consulte Entender os modelos de armazenamento de dados.

  • Lembre-se de que os dados incluem mais do que apenas os dados de aplicativo persistentes. Eles também incluem logs de aplicativo, eventos, mensagens e caches.

  • Adote a persistência poliglota ou soluções que usam uma combinação de tecnologias de armazenamento de dados.

  • Considere o tipo de dados que você tem. Por exemplo, armazene:

    • Dados transacionais em um banco de dados SQL.

    • JSON em um banco de dados de documentos.

    • Telemetria em um banco de dados de série temporal.

    • Logs de aplicativo no Azure Cognitive Search.

    • Blobs no Armazenamento de Blobs do Azure.

  • Priorize a disponibilidade em vez da consistência. O teorema CAP implica que você precisa fazer compensações entre disponibilidade e consistência em um sistema distribuído. Você não pode evitar completamente as partições de rede, que é o outro componente do teorema CAP. Mas você pode adotar um modelo de consistência eventual para obter maior disponibilidade.

  • Considere o conjunto de habilidades da sua equipe de desenvolvimento. Há vantagens em usar a persistência poliglota, mas é possível exagerar. Requer novos conjuntos de habilidades para adotar uma nova tecnologia de armazenamento de dados. Para aproveitar ao máximo a tecnologia, sua equipe de desenvolvimento deve:

    • Otimize as consultas.

    • Ajustar para desempenho.

    • Trabalhe com os padrões de uso apropriados.

Considere estes fatores ao escolher uma tecnologia de armazenamento:

  • Use transações de compensação. Com a persistência poliglota, uma única transação pode gravar dados em vários repositórios. Se houver uma falha, use transações de compensação para desfazer todas as etapas concluídas.

  • Considere contextos limitados, que é um conceito de design controlado por domínio. Um contexto limitado é um limite explícito em torno de um modelo de domínio. Um contexto limitado define a quais partes do domínio o modelo se aplica. Idealmente, um contexto limitado é mapeado para um subdomínio do domínio da empresa. Considere a persistência poliglota para contextos limitados em seu sistema. Por exemplo, os produtos podem aparecer no subdomínio do catálogo de produtos e no subdomínio do estoque de produtos. Mas, provavelmente, esses dois subdomínios têm requisitos diferentes para armazenar, atualizar e consultar produtos.

Facilitação do Azure

O Azure oferece os seguintes serviços:

  • O Azure Functions é um serviço de computação sem servidor que você pode usar para criar orquestração com código mínimo.

  • Os Aplicativos Lógicos do Azure são uma plataforma de integração de fluxo de trabalho sem servidor que você pode usar para criar orquestração com uma GUI ou editando um arquivo de configuração.

  • A Grade de Eventos do Azure é um serviço de distribuição de mensagens de publicação/assinatura altamente escalonável e totalmente gerenciado que oferece padrões flexíveis de consumo de mensagens que usam os protocolos MQTT e HTTP. Com a Grade de Eventos, você pode criar pipelines de dados com dados de dispositivo, criar arquiteturas sem servidor controladas por eventos e integrar aplicativos.

Para saber mais, veja:

Exemplo

Para obter um exemplo de carga de trabalho que determina componentes e seus recursos com base em requisitos, consulte Padrão de aplicativo Web confiável.

Lista de verificação de confiabilidade

Consulte o conjunto completo de recomendações.