Este documento apresenta alguns padrões e práticas para criar apps resilientes e escaláveis, dois objetivos essenciais de muitos exercícios de arquitetura modernos. Uma app bem concebida é dimensionada para cima e para baixo à medida que a procura aumenta e diminui, e é suficientemente resiliente para resistir a interrupções do serviço. A criação e a operação de apps que cumprem estes requisitos exigem um planeamento e um design cuidadosos.
Escalabilidade: ajustar a capacidade para satisfazer a procura
Escalabilidade é a medida da capacidade de um sistema processar quantidades variáveis de trabalho adicionando ou removendo recursos do sistema. Por exemplo, uma app Web escalável é uma app que funciona bem com um ou vários utilizadores e que processa corretamente os picos e as quedas no tráfego.
A flexibilidade para ajustar os recursos consumidos por uma app é um fator empresarial fundamental para a mudança para a nuvem. Com um design adequado, pode reduzir os custos removendo recursos pouco usados sem comprometer o desempenho nem a experiência do utilizador. Da mesma forma, pode manter uma boa experiência do utilizador durante períodos de tráfego elevado adicionando mais recursos. Desta forma, a sua app só pode consumir os recursos necessários para satisfazer a procura.
Google Cloud oferece produtos e funcionalidades para ajudar a criar apps escaláveis e eficientes:
- As máquinas virtuais do Compute Engine e os clusters do Google Kubernetes Engine (GKE) integram-se com os escaladores automáticos que lhe permitem aumentar ou diminuir o consumo de recursos com base nas métricas que definir.
- Google Cloud's plataforma sem servidor oferece computação gerida, base de dados e outros serviços que são rapidamente dimensionados de zero a volumes de pedidos elevados, e só paga o que usa.
- Os produtos de base de dados, como o BigQuery, oSpanner e o Bigtable, podem oferecer um desempenho consistente em tamanhos de dados enormes.
- O Cloud Monitoring fornece métricas nas suas apps e infraestrutura, ajudando a tomar decisões de escalabilidade orientadas por dados.
Resiliência: criar a pensar na capacidade de resistir a falhas
Uma app resiliente é uma app que continua a funcionar apesar das falhas dos componentes do sistema. A resiliência requer planeamento a todos os níveis da sua arquitetura. Isto influencia a forma como organiza a sua infraestrutura e rede, bem como a forma como concebe o armazenamento de apps e dados. A resiliência também se estende às pessoas e à cultura.
Criar e operar apps resilientes é difícil. Isto é particularmente verdade para as apps distribuídas, que podem conter várias camadas de infraestrutura, redes e serviços. Os erros e as indisponibilidades acontecem, e melhorar a resiliência da sua app é um processo contínuo. Com um planeamento cuidadoso, pode melhorar a capacidade da sua app de resistir a falhas. Com processos adequados e uma cultura organizacional, também pode aprender com as falhas para aumentar ainda mais a resiliência da sua app.
Google Cloud oferece ferramentas e serviços para ajudar a criar apps altamente disponíveis e resilientes:
- Google Cloud estão disponíveis em regiões e zonas em todo o mundo, o que lhe permite implementar a sua app para cumprir melhor os seus objetivos de disponibilidade.
- Os grupos de instâncias do Compute Engine e os clusters do GKE podem ser distribuídos e geridos nas zonas disponíveis numa região.
- Os discos persistentes regionais do Compute Engine são replicados de forma síncrona em várias zonas de uma região.
- Google Cloud oferece uma variedade de opções de equilíbrio de carga para gerir o tráfego da sua app, incluindo o equilíbrio de carga global que pode direcionar o tráfego para uma região saudável mais próxima dos seus utilizadores.
- Google Cloud's plataforma sem servidor inclui produtos de computação e base de dados geridos que oferecem redundância e equilíbrio de carga incorporados.
- O Cloud Build executa as suas compilações no Google Cloud e permite-lhe implementar em plataformas como o App Engine, o Compute Engine, o Cloud Run e o GKE.
- O Cloud Monitoring fornece métricas nas suas apps e infraestrutura, o que ajuda a tomar decisões orientadas por dados sobre o desempenho e o estado das suas apps.
Fatores e restrições
Existem vários requisitos e motivações para melhorar a escalabilidade e a resiliência da sua app. Também podem existir restrições que limitam a sua capacidade de atingir os objetivos de escalabilidade e resiliência. A importância relativa destes requisitos e restrições varia consoante o tipo de app, o perfil dos seus utilizadores e a escala e a maturidade da sua organização.
Impulsionadores
Para ajudar a dar prioridade aos seus requisitos, considere os fatores das diferentes partes da sua organização.
Catalisadores de negócios
Os catalisadores comuns do lado da empresa incluem o seguinte:
- Otimize os custos e o consumo de recursos.
- Minimizar o tempo de inatividade da app.
- Certifique-se de que a procura dos utilizadores pode ser satisfeita durante períodos de utilização elevada.
- Melhorar a qualidade e a disponibilidade do serviço.
- Garantir que a experiência do utilizador e a confiança são mantidas durante quaisquer interrupções.
- Aumentar a flexibilidade e a agilidade para lidar com as exigências do mercado em constante mudança.
Motivações de desenvolvimento
Os motivos comuns do lado do desenvolvimento incluem o seguinte:
- Minimizar o tempo gasto na investigação de falhas.
- Aumentar o tempo dedicado ao desenvolvimento de novas funcionalidades.
- Minimize o trabalho repetitivo através da automatização.
- Crie apps com os padrões e as práticas mais recentes da indústria.
Motivações operacionais
Os requisitos a considerar do ponto de vista das operações incluem o seguinte:
- Reduzir a frequência de falhas que requerem intervenção humana.
- Aumentar a capacidade de recuperação automática de falhas.
- Minimize o trabalho repetitivo através da automatização.
- Minimizar o impacto da falha de qualquer componente específico.
Restrições
As restrições podem limitar a sua capacidade de aumentar a escalabilidade e a resiliência da sua app. Certifique-se de que as suas decisões de design não introduzem nem contribuem para estas restrições:
- Dependências de hardware ou software difíceis de dimensionar.
- Dependências de hardware ou software difíceis de operar numa configuração de alta disponibilidade.
- Dependências entre apps.
- Restrições de licenciamento.
- Falta de competências ou experiência nas suas equipas de desenvolvimento e operações.
- Resistência organizacional à automatização.
Padrões e práticas
O resto deste documento define padrões e práticas para ajudar a criar apps resilientes e escaláveis. Estes padrões abrangem todas as partes do ciclo de vida da sua app, incluindo a conceção da infraestrutura, a arquitetura da app, as opções de armazenamento, os processos de implementação e a cultura organizacional.
Existem três temas evidentes nos padrões:
- Automatização. A criação de apps escaláveis e resilientes requer automatização. A automatização do aprovisionamento, dos testes e das implementações de apps da sua infraestrutura aumenta a consistência e a velocidade, e minimiza os erros humanos.
- Acoplamento flexível. Tratar o seu sistema como uma coleção de componentes independentes e fracamente interligados permite flexibilidade e resiliência. A independência abrange a forma como distribui fisicamente os seus recursos e como estrutura a sua app e concebe o seu armazenamento.
- Design orientado por dados. A recolha de métricas para compreender o comportamento da sua app é fundamental. As decisões sobre quando dimensionar a sua app ou se um determinado serviço não está em bom estado têm de se basear em dados. As métricas e os registos devem ser funcionalidades essenciais.
Automatize o aprovisionamento da sua infraestrutura
Crie uma infraestrutura imutável através da automatização para melhorar a consistência dos seus ambientes e aumentar o sucesso das suas implementações.
Trate a sua infraestrutura como código
A infraestrutura como código (IaC) é uma técnica que incentiva a tratar o aprovisionamento e a configuração da infraestrutura da mesma forma que trata o código da aplicação. A sua lógica de aprovisionamento e configuração é armazenada no controlo de origem para que seja detetável e possa ser controlada por versões e auditada. Uma vez que se encontra num repositório de código, pode tirar partido da integração contínua e dos pipelines de implementação contínua (CI/CD), para que todas as alterações à sua configuração possam ser testadas e implementadas automaticamente.
Ao remover os passos manuais do aprovisionamento da sua infraestrutura, a IaC minimiza os erros humanos e melhora a consistência e a reprodutibilidade das suas apps e ambientes. Desta forma, a adoção da IaC aumenta a resiliência das suas apps.
O Infrastructure Manager permite-lhe automatizar a criação e a gestão de recursos Google Cloud . Em alternativa, o Config Connector permite-lhe gerir os seus recursos através de técnicas e fluxos de trabalho do Kubernetes. OGoogle Cloud também tem suporte integrado para ferramentas de IaC populares de terceiros, incluindo o Terraform, o Chef e o Puppet.
Crie uma infraestrutura imutável
A infraestrutura imutável é uma filosofia que se baseia nas vantagens da infraestrutura como código. A infraestrutura imutável exige que os recursos nunca sejam modificados após a implementação. Se for necessário atualizar uma máquina virtual, um cluster do Kubernetes ou uma regra de firewall, pode atualizar a configuração do recurso no repositório de origem. Depois de testar e validar as alterações, reimplemente totalmente o recurso com a nova configuração. Por outras palavras, em vez de ajustar os recursos, volta a criá-los.
A criação de uma infraestrutura imutável leva a implementações e reversões mais previsíveis. Também mitiga problemas comuns em infraestruturas mutáveis, como a deriva de configuração e os servidores snowflake. Desta forma, a adoção de uma infraestrutura imutável melhora ainda mais a consistência e a fiabilidade dos seus ambientes.
Crie em função da alta disponibilidade
A disponibilidade é uma medida da fração de tempo em que um serviço é utilizável. A disponibilidade é frequentemente usada como um indicador fundamental do estado geral do serviço. As arquiteturas de elevada disponibilidade visam maximizar a disponibilidade dos serviços, normalmente através da implementação redundante de componentes. Em termos mais simples, alcançar a elevada disponibilidade envolve normalmente a distribuição de recursos de computação, o equilíbrio de carga e a replicação de dados.
Distribuir recursos fisicamente
Os serviçosGoogle Cloud estão disponíveis em localizações de todo o mundo. Estas localizações estão divididas em regiões e zonas. A forma como implementa a sua app nestas regiões e zonas afeta a disponibilidade, a latência e outras propriedades da sua app. Para mais informações, consulte as práticas recomendadas para a seleção de regiões do Compute Engine.
A redundância é a duplicação de componentes de um sistema para aumentar a disponibilidade geral desse sistema. Na Google Cloud, a redundância é normalmente alcançada através da implementação da sua app ou serviço em várias zonas ou até mesmo em várias regiões. Se um serviço existir em várias zonas ou regiões, pode resistir melhor a interrupções do serviço numa zona ou região específica. Embora a Google Cloud envide todos os esforços para evitar tais interrupções, determinados eventos são imprevisíveis e é melhor estar preparado.
Com os grupos de instâncias geridas do Compute Engine, pode distribuir instâncias de máquinas virtuais por várias zonas numa região e gerir as instâncias como uma unidade lógica. Google Cloud Também oferece discos persistentes regionais para replicar automaticamente os seus dados em duas zonas numa região.
Da mesma forma, pode melhorar a disponibilidade e a resiliência das suas apps implementadas no GKE criando clusters regionais. Um cluster regional distribui os componentes do plano de controlo do GKE, os nós e os pods por várias zonas numa região. Uma vez que os componentes do plano de controlo estão distribuídos, pode continuar a aceder ao plano de controlo do cluster mesmo durante uma indisponibilidade que envolva uma ou mais (mas não todas) zonas.
Favoreça os serviços geridos
Em vez de instalar, suportar e operar de forma independente todas as partes da sua pilha de aplicações, pode usar serviços geridos para consumir partes da sua pilha de aplicações como serviços. Por exemplo, em vez de instalar e gerir uma base de dados MySQL em máquinas virtuais (VMs), pode usar uma base de dados MySQL fornecida pelo Cloud SQL. Em seguida, recebe um contrato de nível de serviço (SLA) de disponibilidade e pode confiar no Google Cloud para gerir a replicação de dados, as cópias de segurança e a infraestrutura subjacente. Ao usar serviços geridos, pode passar menos tempo a gerir a infraestrutura e mais tempo a melhorar a fiabilidade da sua app.
Muitos dos serviços de computação, bases de dados e armazenamento geridos da Google Cloud oferecem redundância incorporada, o que pode ajudar a atingir os seus objetivos de disponibilidade. Muitos destes serviços oferecem um modelo regional, o que significa que a infraestrutura que executa a sua app está localizada numa região específica e é gerida pela Google para estar disponível de forma redundante em todas as zonas dessa região. Google CloudSe uma zona ficar indisponível, a sua app ou dados são publicados automaticamente a partir de outra zona na região.
Determinados serviços de bases de dados e armazenamento também oferecem disponibilidade multirregional, o que significa que a infraestrutura que executa a sua app está localizada em várias regiões. Os serviços multirregionais podem resistir à perda de uma região inteira, mas normalmente ao custo de uma latência mais elevada.
Equilibre a carga em cada nível
O balanceamento de carga permite-lhe distribuir o tráfego entre grupos de recursos. Quando distribui o tráfego, ajuda a garantir que os recursos individuais não ficam sobrecarregados enquanto outros permanecem inativos. A maioria dos equilibradores de carga também oferece funcionalidades de verificação do estado de funcionamento para ajudar a garantir que o tráfego não é encaminhado para recursos com problemas ou indisponíveis.
Google Cloud oferece várias opções de equilíbrio de carga. Se a sua app for executada no Compute Engine ou no GKE, pode escolher o tipo de equilibrador de carga mais adequado consoante o tipo, a origem e outros aspetos do tráfego. Para mais informações, consulte a vista geral do balanceamento de carga e a vista geral da rede do GKE.
Em alternativa, alguns serviços geridos pela Google, como o App Engine e o Cloud Run, equilibram automaticamente a carga do tráfego. Google Cloud
É uma prática comum equilibrar a carga de pedidos recebidos de origens externas, como clientes Web ou para dispositivos móveis. No entanto, a utilização de balanceadores de carga entre diferentes serviços ou níveis na sua app também pode aumentar a resiliência e a flexibilidade.O Google Cloud fornece balanceamento de carga interno de camada 4 e camada 7 para este fim.
O diagrama seguinte mostra um balanceador de carga externo que distribui o tráfego global por duas regiões, us-central1
e asia-east1
. Também mostra o
balanceamento de carga interno a distribuir o tráfego da camada Web para a camada
interna em cada região.
Monitorize a sua infraestrutura e apps
Antes de poder decidir como melhorar a resiliência e a escalabilidade da sua app, tem de compreender o respetivo comportamento. Ter acesso a um conjunto abrangente de métricas relevantes e séries cronológicas sobre o desempenho e o estado da sua app pode ajudar a descobrir potenciais problemas antes de causarem uma indisponibilidade. Também podem ajudar a diagnosticar e resolver uma indisponibilidade, se ocorrer. O capítulo Monitorizar sistemas distribuídos no livro de EFS da Google oferece uma boa vista geral de algumas abordagens à monitorização.
Além de fornecerem estatísticas sobre o estado da sua app, as métricas também podem ser usadas para controlar o comportamento do dimensionamento automático dos seus serviços.
O Cloud Monitoring é Google Cloud; a ferramenta de monitorização integrada. O Cloud Monitoring introduz eventos, métricas e metadados, e fornece estatísticas através de painéis de controlo e alertas. A maioria dos Google Cloud serviços envia automaticamente métricas para o Cloud Monitoring e Google Cloud também suporta muitas origens de terceiros. O Cloud Monitoring também pode ser usado como um back-end para ferramentas de monitorização de código aberto populares, oferecendo um "painel único" com o qual observar a sua app.
Monitorize a todos os níveis
A recolha de métricas em vários níveis ou camadas na sua arquitetura oferece uma imagem holística do estado e do comportamento da sua app.
Monitorização da infraestrutura
A monitorização ao nível da infraestrutura fornece o estado e o desempenho de referência para a sua app. Esta abordagem à monitorização capta informações como a carga da CPU, a utilização da memória e o número de bytes escritos no disco. Estas métricas podem indicar que uma máquina está sobrecarregada ou não está a funcionar como esperado.
Além das métricas recolhidas automaticamente, o Cloud Monitoring fornece um agente que pode ser instalado para recolher informações mais detalhadas das VMs do Compute Engine, incluindo de apps de terceiros em execução nessas máquinas.
Monitorização de apps
Recomendamos que capture métricas ao nível da app. Por exemplo, pode querer medir o tempo necessário para executar uma consulta específica ou o tempo necessário para realizar uma sequência relacionada de chamadas de serviço. Estas métricas ao nível da app são definidas por si. Capturam informações que as métricas do Cloud Monitoring incorporadas não conseguem. As métricas ao nível da app podem captar condições agregadas que refletem mais de perto os fluxos de trabalho principais e podem revelar problemas que as métricas de infraestrutura de baixo nível não revelam.
Também recomendamos a utilização do OpenTelemetry para captar as métricas ao nível da app. O OpenTelemetry oferece uma única norma aberta para dados de telemetria. Use o OpenTelemetry para recolher e exportar dados das suas aplicações e infraestrutura prioritárias na nuvem. Em seguida, pode monitorizar e analisar os dados de telemetria exportados.
Monitorização de serviços
Para apps distribuídas e baseadas em microsserviços, é importante monitorizar as interações entre os diferentes serviços e componentes nas suas apps. Estas métricas podem ajudar a diagnosticar problemas, como o aumento do número de erros ou a latência entre serviços.
O Cloud Service Mesh é uma malha de serviços disponível no Google Cloud que lhe permite gerir, observar, medir e proteger os seus microsserviços na infraestrutura escolhida, dentro e fora doGoogle Cloud.
Monitorização ponto a ponto
A monitorização ponto a ponto, também denominada monitorização do utilizador final, testa o comportamento visível externamente da forma como um utilizador o vê. Este tipo de monitorização verifica se um utilizador consegue concluir ações críticas dentro dos limites definidos. Esta monitorização detalhada pode detetar erros ou latência que a monitorização mais detalhada pode não detetar e revela a disponibilidade conforme percebida pelo utilizador.
Exponha o estado de funcionamento das suas apps
Um sistema de elevada disponibilidade tem de ter uma forma de determinar que partes do sistema estão em bom estado e a funcionar corretamente. Se determinados recursos parecerem não saudáveis, o sistema pode enviar pedidos para outro local. Normalmente, as verificações de saúde envolvem extrair dados de um ponto final para determinar o estado ou a saúde de um serviço.
A verificação de funcionamento é uma responsabilidade fundamental dos balanceadores de carga. Quando cria um balanceador de carga associado a um grupo de instâncias de máquinas virtuais, também define uma verificação de funcionamento. A verificação de estado define a forma como o equilibrador de carga comunica com as máquinas virtuais para avaliar se determinadas instâncias devem continuar a receber tráfego. As verificações de estado do balanceador de carga também podem ser usadas para recuperar automaticamente grupos de instâncias, de modo que as máquinas com problemas sejam recriadas. Se estiver a ser executado no GKE e a equilibrar a carga do tráfego externo através de um recurso de entrada, o GKE cria automaticamente verificações de estado adequadas para o equilibrador de carga.
O Kubernetes tem suporte integrado para sondas de atividade e disponibilidade. Estas sondas ajudam o orquestrador do Kubernetes a decidir como gerir pods e pedidos no seu cluster. Se a sua app estiver implementada no Kubernetes, é uma boa ideia expor o estado de funcionamento da app a estas sondagens através de pontos finais adequados.
Estabeleça métricas principais
A monitorização e a verificação do estado de funcionamento fornecem-lhe métricas sobre o comportamento e o estado da sua app. O passo seguinte é analisar essas métricas para determinar quais são as mais descritivas ou com maior impacto. As principais métricas variam consoante a plataforma na qual a app está implementada e o trabalho que a app está a fazer.
É pouco provável que encontre apenas uma métrica que indique se deve dimensionar a sua app ou que um serviço específico não está em bom estado. Muitas vezes, é uma combinação de fatores que, em conjunto, indicam um determinado conjunto de condições. Com o Cloud Monitoring, pode criar métricas personalizadas para ajudar a captar estas condições. O livro SRE da Google defende quatro sinais fundamentais para monitorizar um sistema virado para o utilizador: latência, tráfego, erros e saturação.
Considere também a sua tolerância a valores atípicos. Usar um valor médio ou mediano para medir o estado ou o desempenho pode não ser a melhor escolha, porque estas medidas podem ocultar desequilíbrios significativos. Por isso, é importante considerar a distribuição das métricas. O percentil 99 pode ser uma medida mais informativa do que a média.
Defina objetivos ao nível do serviço (SLOs)
Pode usar as métricas recolhidas pelo seu sistema de monitorização para definir objetivos de nível de serviço (SLOs). Os SLOs especificam um nível de desempenho ou fiabilidade alvo para o seu serviço. Os SLOs são um pilar fundamental das práticas de EFS e são descritos detalhadamente no capítulo Objetivos ao nível do serviço no livro de EFS, bem como no capítulo Implementar SLOs no livro de EFS.
Pode usar a monitorização de serviços para definir SLOs com base nas métricas no Cloud Monitoring. Pode criar políticas de alerta em SLOs para saber se está em risco de violar um SLO.
Armazene as métricas
As métricas do seu sistema de monitorização são úteis a curto prazo para ajudar com as verificações de funcionamento em tempo real ou para investigar problemas recentes. O Cloud Monitoring retém as suas métricas durante várias semanas para satisfazer melhor esses exemplos de utilização.
No entanto, também é útil armazenar as métricas de monitorização para análise a longo prazo. Ter acesso a um registo histórico pode ajudar a adotar uma abordagem baseada em dados para refinar a arquitetura da sua app. Pode usar os dados recolhidos durante e após uma indisponibilidade para identificar gargalos e interdependências nas suas apps. Também pode usar os dados para ajudar a criar e validar testes relevantes.
Os dados do histórico também podem ajudar a validar se a sua app está a apoiar os objetivos da empresa durante períodos importantes. Por exemplo, os dados podem ajudar a analisar a forma como a sua app foi dimensionada durante eventos promocionais de tráfego elevado ao longo dos últimos trimestres ou até anos.
Para ver detalhes sobre como exportar e armazenar as suas métricas, consulte a solução de exportação de métricas do Cloud Monitoring.
Determine o perfil de escalabilidade
Quer que a sua app cumpra os objetivos de desempenho e experiência do utilizador sem exceder o aprovisionamento de recursos.
O diagrama seguinte mostra uma representação simplificada do perfil de escalabilidade de uma app. A app mantém um nível de base de recursos e usa a criação de uma escala automática para responder a alterações na procura.
Equilibre o custo e a experiência do utilizador
Decidir se deve dimensionar a sua app consiste fundamentalmente em equilibrar o custo com a experiência do utilizador. Decida qual é o nível mínimo aceitável de desempenho e, potencialmente, onde definir um limite máximo. Estes limites variam de app para app e também podem variar entre diferentes componentes ou serviços numa única app.
Por exemplo, uma app Web ou para dispositivos móveis orientada para o consumidor pode ter objetivos de latência rigorosos. A investigação mostra que, mesmo pequenos atrasos, podem afetar negativamente a forma como os utilizadores percebem a sua app, o que resulta em menos conversões e inscrições. Por conseguinte, é importante garantir que a sua app tem capacidade de publicação suficiente para responder rapidamente aos pedidos dos utilizadores. Neste caso, os custos mais elevados da execução de mais servidores Web podem ser justificados.
A relação custo/desempenho pode ser diferente para uma app interna não essencial para a empresa, em que os utilizadores são provavelmente mais tolerantes a pequenos atrasos. Por isso, o seu perfil de escalabilidade pode ser menos agressivo. Neste caso, manter os custos baixos pode ser mais importante do que otimizar a experiência do utilizador.
Defina recursos de base
Outro componente essencial do seu perfil de escalabilidade é decidir sobre um conjunto mínimo adequado de recursos.
Normalmente, as máquinas virtuais do Compute Engine ou os clusters do GKE demoram a aumentar a escala, porque é necessário criar e inicializar novos nós. Por conseguinte, pode ser necessário manter um conjunto mínimo de recursos, mesmo que não haja tráfego. Mais uma vez, a extensão dos recursos de base é influenciada pelo tipo de app e perfil de tráfego.
Por outro lado, as tecnologias sem servidor, como o App Engine, as funções do Cloud Run e o Cloud Run, são concebidas para serem reduzidas a zero e para serem iniciadas e dimensionadas rapidamente, mesmo no caso de um arranque a frio. Consoante o tipo de app e o perfil de tráfego, estas tecnologias podem oferecer eficiências para partes da sua app.
Configure a escala automática
A dimensionamento automático ajuda a dimensionar automaticamente os recursos de computação consumidos pela sua app. Normalmente, o dimensionamento automático ocorre quando determinadas métricas são excedidas ou as condições são satisfeitas. Por exemplo, se as latências de pedidos para o seu nível Web começarem a exceder um determinado valor, pode querer adicionar automaticamente mais máquinas para aumentar a capacidade de publicação.
Muitos Google Cloud produtos de computação têm funcionalidades de dimensionamento automático. Os serviços geridos sem servidor, como o Cloud Run, as funções do Cloud Run e o App Engine, foram concebidos para serem dimensionados rapidamente. Normalmente, estes serviços oferecem opções de configuração para limitar ou influenciar o comportamento do dimensionamento automático, mas, em geral, grande parte do comportamento do dimensionador automático está oculta do operador.
O Compute Engine e o GKE oferecem mais opções para controlar o comportamento de escalabilidade. Com o Compute Engine, pode dimensionar com base em várias entradas, incluindo métricas personalizadas do Cloud Monitoring e capacidade de fornecimento do balanceador de carga. Pode definir limites mínimos e máximos no comportamento de escalabilidade e pode definir uma política de escalabilidade automática com vários sinais para processar diferentes cenários. Tal como no GKE, pode configurar o dimensionamento automático do cluster para adicionar ou remover nós com base na carga de trabalho ou nas métricas dos pods, ou em métricas externas ao cluster.
Recomendamos que configure o comportamento do dimensionamento automático com base nas principais métricas da app, no seu perfil de custos e no nível mínimo necessário de recursos definido.
Minimize o tempo de arranque
Para que o escalamento seja eficaz, tem de ocorrer com rapidez suficiente para processar o aumento da carga. Isto é especialmente verdade quando adiciona capacidade de computação ou publicação.
Use imagens pré-renderizadas
Se a sua app for executada em VMs do Compute Engine, é provável que tenha de instalar software e configurar as instâncias para executar a app. Embora possa usar scripts de arranque para configurar novas instâncias, uma forma mais eficiente é criar uma imagem personalizada. Uma imagem personalizada é um disco de arranque que configura com o software e a configuração específicos da sua app.
Para mais informações sobre a gestão de imagens, consulte o artigo Práticas recomendadas de gestão de imagens.
Depois de criar a imagem, pode definir um modelo de instância. Os modelos de instâncias combinam a imagem do disco de arranque, o tipo de máquina e outras propriedades da instância. Em seguida, pode usar um modelo de instância para criar instâncias de VM individuais ou um grupo de instâncias gerido. Os modelos de instâncias são uma forma conveniente de guardar a configuração de uma instância de VM para que a possa usar mais tarde para criar novas instâncias de VM idênticas.
Embora a criação de imagens personalizadas e modelos de instâncias possa aumentar a velocidade de implementação, também pode aumentar os custos de manutenção, uma vez que as imagens podem ter de ser atualizadas com maior frequência. Para mais informações, consulte os documentos sobre como equilibrar a configuração da imagem e a velocidade de implementação.
Coloque a sua app num contentor
Uma alternativa à criação de instâncias de VMs personalizadas é colocar a sua app num contentor. Um contentor é um pacote de software executável, autónomo e leve que inclui tudo o que é necessário para executar uma app: código, tempo de execução, ferramentas do sistema, bibliotecas do sistema e definições. Estas caraterísticas tornam as apps contentorizadas mais portáteis, fáceis de implementar e fáceis de manter em grande escala do que as máquinas virtuais. Normalmente, os contentores também são rápidos de iniciar, o que os torna adequados para apps escaláveis e resilientes.
Google Cloud oferece vários serviços para executar os contentores de apps. O Cloud Run oferece uma plataforma de computação gerida sem servidor para alojar os seus contentores sem estado. O ambiente App Engine Flexible aloja os seus contentores numa plataforma gerida como serviço (PaaS). O GKE oferece um ambiente Kubernetes gerido para alojar e orquestrar as suas apps contentorizadas. Também pode executar os seus contentores de apps no Compute Engine quando precisar de controlo total sobre o seu ambiente de contentores.
Otimize a sua app para um arranque rápido
Além de garantir que a sua infraestrutura e app podem ser implementadas da forma mais eficiente possível, também é importante garantir que a app fica online rapidamente.
As otimizações adequadas para a sua app variam consoante as características da app e a plataforma de execução. É importante fazer o seguinte:
- Encontre e elimine gargalos ao criar perfis das secções críticas da sua app que são invocadas no arranque.
- Reduza o tempo de arranque inicial implementando técnicas como a inicialização diferida, particularmente de recursos dispendiosos.
- Minimize as dependências da app que possam ter de ser carregadas no momento do arranque.
Favoreça as arquiteturas modulares
Pode aumentar a flexibilidade da sua app escolhendo arquiteturas que permitem a implementação, a gestão e o dimensionamento independentes dos componentes. Este padrão também pode melhorar a capacidade de recuperação eliminando pontos únicos de falha.
Divida a sua app em serviços independentes
Se criar a sua app como um conjunto de serviços independentes e pouco acoplados, pode aumentar a flexibilidade da app. Se adotar um design com acoplamento fraco, permite que os seus serviços sejam lançados e implementados de forma independente. Além de muitas outras vantagens, esta abordagem permite que esses serviços usem diferentes conjuntos de tecnologias e sejam geridos por diferentes equipas. Esta abordagem de acoplamento fraco é o tema principal de padrões de arquitetura como microsserviços e SOA.
À medida que pondera como definir limites para os seus serviços, os requisitos de disponibilidade e escalabilidade são dimensões essenciais. Por exemplo, se um determinado componente tiver um requisito de disponibilidade ou um perfil de escalabilidade diferente dos outros componentes, pode ser um bom candidato para um serviço autónomo.
Procure usar aplicações sem estado
Uma app ou um serviço sem estado não retém nenhum estado nem dados persistentes locais. Um modelo sem estado garante que pode processar cada pedido ou interação com o serviço independentemente dos pedidos anteriores. Este modelo facilita a escalabilidade e a capacidade de recuperação, porque significa que o serviço pode crescer, diminuir ou ser reiniciado sem perder dados necessários para processar quaisquer processos ou pedidos em curso. A ausência de estado é especialmente importante quando usa um escalador automático, porque as instâncias, os nós ou os pods que alojam o serviço podem ser criados e destruídos inesperadamente.
Pode não ser possível que todos os seus serviços sejam sem estado. Nesse caso, seja explícito sobre os serviços que requerem estado. Ao garantir uma separação clara dos serviços sem estado e com estado, pode garantir uma escalabilidade simples para os serviços sem estado, ao mesmo tempo que adota uma abordagem mais ponderada para os serviços com estado.
Faça a gestão da comunicação entre serviços
Um dos desafios das arquiteturas de microserviços distribuídos é a gestão da comunicação entre serviços. À medida que a sua rede de serviços cresce, é provável que as interdependências dos serviços também aumentem. Não quer que a falha de um serviço resulte na falha de outros serviços, por vezes, denominada falha em cascata.
Pode ajudar a reduzir o tráfego para um serviço sobrecarregado ou com falhas através da adoção de técnicas como o padrão de interruptor de circuito, recuos exponenciais e degradação gradual. Estes padrões aumentam a capacidade de recuperação da sua app, dando aos serviços sobrecarregados a oportunidade de recuperação ou processando graciosamente os estados de erro. Para mais informações, consulte o capítulo Como resolver falhas em cascata no livro SRE da Google.
A utilização de uma rede de serviços pode ajudar a gerir o tráfego nos seus serviços distribuídos. Uma malha de serviços é um software que liga os serviços e ajuda a separar a lógica empresarial da rede. Normalmente, uma malha de serviços oferece funcionalidades de resiliência, como novas tentativas de pedidos, failovers e disjuntores.
Use a tecnologia de base de dados e armazenamento adequada
É difícil dimensionar e tornar resilientes determinadas bases de dados e tipos de armazenamento. Certifique-se de que as suas escolhas de base de dados não restringem a disponibilidade e a escalabilidade da app.
Avalie as suas necessidades de base de dados
O padrão de conceber a sua app como um conjunto de serviços independentes também se aplica às suas bases de dados e armazenamento. Pode ser adequado escolher diferentes tipos de armazenamento para diferentes partes da sua app, o que resulta num armazenamento heterogéneo.
As apps convencionais funcionam frequentemente em exclusivo com bases de dados relacionais. As bases de dados relacionais oferecem funcionalidades úteis, como transações, consistência forte, integridade referencial e consultas sofisticadas em várias tabelas. Estas funcionalidades tornam as bases de dados relacionais uma boa escolha para muitas funcionalidades comuns de apps. No entanto, as bases de dados relacionais também têm algumas restrições. Normalmente, são difíceis de dimensionar e requerem uma gestão cuidadosa numa configuração de alta disponibilidade. Uma base de dados relacional pode não ser a melhor opção para todas as suas necessidades de base de dados.
As bases de dados não relacionais, frequentemente denominadas bases de dados NoSQL, adotam uma abordagem diferente. Embora os detalhes variem entre os produtos, as bases de dados NoSQL sacrificam normalmente algumas funcionalidades das bases de dados relacionais em favor de uma maior disponibilidade e uma escalabilidade mais fácil. Em termos do teorema CAP, as bases de dados NoSQL escolhem frequentemente a disponibilidade em detrimento da consistência.
Se uma base de dados NoSQL é adequada, depende frequentemente do grau de consistência necessário. Se o seu modelo de dados para um serviço específico não exigir todas as funcionalidades de um SGBDR e puder ser concebido para ser eventualmente consistente, a escolha de uma base de dados NoSQL pode oferecer maior disponibilidade e escalabilidade.
No domínio da gestão de dados, as bases de dados relacionais e não relacionais são frequentemente vistas como tecnologias complementares, em vez de concorrentes. Ao usar estrategicamente ambos os tipos de bases de dados, as organizações podem tirar partido das vantagens de cada uma para alcançar resultados ideais no armazenamento, na obtenção e na análise de dados.
Além de uma variedade de bases de dados relacionais e NoSQL, Google Cloud também oferece Spanner, uma base de dados fortemente consistente, altamente disponível e distribuída globalmente com suporte para SQL. Para informações sobre como escolher uma base de dados adequada no Google Cloud, consulte as Google Cloud bases de dados.
Implemente a colocação em cache
O objetivo principal de uma cache é aumentar o desempenho da obtenção de dados, reduzindo a necessidade de aceder à camada de armazenamento subjacente mais lenta.
O armazenamento em cache suporta uma escalabilidade melhorada, reduzindo a dependência do armazenamento baseado em disco. Uma vez que os pedidos podem ser publicados a partir da memória, as latências dos pedidos para a camada de armazenamento são reduzidas, o que permite normalmente que o seu serviço processe mais pedidos. Além disso, o armazenamento em cache pode reduzir a carga nos serviços que estão a jusante da sua app, especialmente bases de dados, permitindo que outros componentes que interagem com esse serviço a jusante também sejam mais escaláveis ou escaláveis.
O armazenamento em cache também pode aumentar a capacidade de recuperação através do suporte de técnicas como a degradação elegante. Se a camada de armazenamento subjacente estiver sobrecarregada ou indisponível, a cache pode continuar a processar pedidos. Mesmo que os dados devolvidos da cache possam estar incompletos ou desatualizados, isso pode ser aceitável para determinados cenários.
O Memorystore for Redis oferece um serviço totalmente gerido com tecnologia do armazenamento de dados na memória Redis. O Memorystore for Redis oferece acesso de baixa latência e elevado débito para dados com muito acesso. Pode ser implementado numa configuração de alta disponibilidade que oferece replicação entre zonas e comutação por falha automática.
Modernize os seus processos e cultura de desenvolvimento
O DevOps pode ser considerado uma vasta coleção de processos, cultura e ferramentas que promovem a agilidade e a redução do tempo de lançamento no mercado de apps e funcionalidades, dividindo os silos entre o desenvolvimento, as operações e as equipas relacionadas. As técnicas de DevOps visam melhorar a qualidade e a fiabilidade do software.
Uma discussão detalhada sobre o DevOps ultrapassa o âmbito deste documento, mas alguns aspetos importantes relacionados com a melhoria da fiabilidade e da resiliência da sua app são abordados nas secções seguintes. Para mais detalhes, consulte a Google Cloud página do DevOps.
Design para testabilidade
Os testes automatizados são um componente fundamental das práticas de fornecimento de software modernas. A capacidade de executar um conjunto abrangente de testes de unidades, integração e sistemas é essencial para verificar se a sua app se comporta como esperado e se pode avançar para a fase seguinte do ciclo de implementação. A capacidade de teste é um critério de design fundamental para a sua app.
Recomendamos que use testes unitários para a maioria dos seus testes, porque são rápidos de executar e, normalmente, fáceis de manter. Também recomendamos que automatize os testes de sistema e de integração de nível superior. Estes testes são muito simplificados se adotar técnicas de infraestrutura como código, porque os ambientes e os recursos de teste dedicados podem ser criados a pedido e, em seguida, desativados quando os testes estiverem concluídos.
À medida que a percentagem da sua base de código coberta por testes aumenta, reduz a incerteza e a potencial diminuição da fiabilidade de cada alteração de código. Uma cobertura de testes adequada significa que pode fazer mais alterações antes de a fiabilidade ficar abaixo de um nível aceitável.
Os testes automatizados são um componente integral da integração contínua. A execução de um conjunto robusto de testes automatizados em cada commit de código fornece feedback rápido sobre as alterações, melhorando a qualidade e a fiabilidade do seu software. Google CloudAs ferramentas nativas, como o Cloud Build, e as ferramentas de terceiros, como o Jenkins, podem ajudar a implementar a integração contínua.
Automatize as suas implementações
A integração contínua e a automatização de testes abrangente dão-lhe confiança na estabilidade do seu software. Quando estiverem implementadas, o passo seguinte é automatizar a implementação da sua app. O nível de automatização da implementação varia consoante a maturidade da sua organização.
A escolha de uma estratégia de implementação adequada é essencial para minimizar os riscos associados à implementação de novo software. Com a estratégia certa, pode aumentar gradualmente a exposição de novas versões a públicos-alvo maiores, verificando o comportamento ao longo do processo. Também pode definir disposições claras para a reversão se ocorrerem problemas.
Adote práticas de EFS para lidar com falhas
Para apps distribuídas que operam em grande escala, algum grau de falha num ou mais componentes é comum. Se adotar os padrões abordados neste documento, a sua app pode processar melhor as interrupções causadas por uma versão de software defeituosa, o encerramento inesperado de máquinas virtuais ou até mesmo uma indisponibilidade da infraestrutura que afeta uma zona inteira.
No entanto, mesmo com um design de apps cuidadoso, encontra inevitavelmente eventos inesperados que requerem intervenção humana. Se implementar processos estruturados para gerir estes eventos, pode reduzir significativamente o respetivo impacto e resolvê-los mais rapidamente. Além disso, se analisar as causas e as respostas ao evento, pode ajudar a proteger a sua app contra eventos semelhantes no futuro.
Os processos fortes para gerir incidentes e realizar investigações "postmortem" são princípios fundamentais da SRE. Embora a implementação das práticas completas da SRE da Google possa não ser prática para a sua organização, se adotar, pelo menos, um conjunto mínimo de diretrizes, pode melhorar a resiliência da sua app. Os apêndices no livro de SRE contêm alguns modelos que podem ajudar a moldar os seus processos.
Valide e reveja a sua arquitetura
À medida que a sua app evolui, o comportamento dos utilizadores, os perfis de tráfego e até as prioridades da empresa podem mudar. Da mesma forma, outros serviços ou infraestrutura dos quais a sua app depende podem evoluir. Por conseguinte, é importante testar e validar periodicamente a resiliência e a escalabilidade da sua app.
Teste a sua resiliência
É fundamental testar se a sua app responde a falhas da forma esperada. O tema geral é que a melhor forma de evitar o fracasso é introduzir o fracasso e aprender com ele.
A simulação e a introdução de falhas são complexas. Além de validar o comportamento da sua app ou serviço, também tem de garantir que são gerados alertas esperados e que são geradas métricas adequadas. Recomendamos uma abordagem estruturada, em que introduz falhas básicas e, em seguida, aumenta a complexidade.
Por exemplo, pode proceder da seguinte forma, validando e documentando o comportamento em cada fase:
- Introduza falhas intermitentes.
- Bloquear o acesso às dependências do serviço.
- Bloquear toda a comunicação de rede.
- Terminar anfitriões.
Para ver detalhes, consulte o vídeo Destruir os seus sistemas para os tornar indestrutíveis do Google Cloud Next 2019.
Se estiver a usar uma malha de serviços como o Istio para gerir os serviços da sua app, pode injetar falhas na camada de aplicação em vez de terminar pods ou máquinas, ou pode injetar pacotes danificados na camada TCP. Pode introduzir atrasos para simular a latência da rede ou um sistema a montante sobrecarregado. Também pode introduzir anulações, que imitam falhas nos sistemas a montante.
Teste o comportamento de escalabilidade
Recomendamos que use testes não funcionais automatizados para verificar se a sua app é dimensionada conforme esperado. Muitas vezes, esta validação é combinada com testes de desempenho ou de carga. Pode usar ferramentas como o hey para enviar carga para uma app Web. Para um exemplo mais detalhado que mostre como fazer testes de carga num ponto final REST, consulte o artigo Testes de carga distribuídos com o Google Kubernetes Engine.
Uma abordagem comum é garantir que as principais métricas permanecem dentro dos níveis esperados para diferentes cargas. Por exemplo, se estiver a testar a escalabilidade da sua camada Web, pode medir as latências médias dos pedidos para volumes irregulares de pedidos de utilizadores. Da mesma forma, para uma funcionalidade de processamento de back-end, pode medir o tempo médio de processamento de tarefas quando o volume de tarefas aumenta subitamente.
Além disso, quer que os testes meçam se o número de recursos criados para processar a carga de teste está dentro do intervalo esperado. Por exemplo, os seus testes podem verificar se o número de VMs criadas para processar algumas tarefas de back-end não excede um determinado valor.
Também é importante testar casos extremos. Qual é o comportamento da sua app ou serviço quando os limites de escalabilidade máximos são atingidos? Qual é o comportamento se o seu serviço estiver a diminuir a escala e, em seguida, a carga aumentar repentinamente novamente?
Crie sempre a arquitetura
O mundo da tecnologia move-se rapidamente, e isto é especialmente verdade no que diz respeito à nuvem. Os novos produtos e funcionalidades são lançados com frequência, surgem novos padrões e as exigências dos seus utilizadores e partes interessadas internas continuam a aumentar.
Conforme definido na publicação no blogue sobre os princípios da arquitetura nativa da nuvem, procure sempre formas de refinar, simplificar e melhorar a arquitetura das suas apps. Os sistemas de software são entidades dinâmicas e têm de se adaptar para refletir as suas prioridades em constante mudança.
O que se segue?
- Leia a publicação no blogue sobre os princípios da arquitetura nativa da nuvem.
- Leia os livros de SRE para ver detalhes sobre como o ambiente de produção da Google é gerido.
- Saiba mais sobre como o DevOps no Google Cloud pode melhorar a qualidade e a fiabilidade do seu software.
- Explore arquiteturas de referência, diagramas e práticas recomendadas sobre o Google Cloud. Consulte o nosso Centro de arquitetura na nuvem.