Projetar uma arquitetura de aplicativo distribuída geograficamente
Quando nossos componentes de rede encaminham solicitações para várias regiões para mitigar os efeitos de uma interrupção regional, devemos projetar serviços de aplicativos que possam responder a essas solicitações em regiões primárias e de espera.
Lembre-se de que planejamos configurar o Azure Front Door com atribuição de back-end prioritária. Atribuímos a região Leste dos EUA como nossa região principal e a região Oeste dos EUA como nossa região de espera. Quando ocorre uma falha regional, as solicitações são encaminhadas para o Serviço de Aplicativo na região sem falha. Temos que configurar recursos em cada região para dar suporte a esses failovers para acesso do usuário, armazenamento replicado e código do aplicativo.
Aqui, examinamos os serviços de aplicativos em nossa solução e determinamos se eles precisam ser modificados para funcionar em uma arquitetura de várias regiões. Especificamente, examinamos o Ative Directory, armazenamento de conteúdo estático, aplicativos Web, APIs Web, filas, funções do Azure e caches de dados.
Microsoft Entra ID
Em nosso portal de rastreamento de remessas, os usuários podem acompanhar a entrega de suas compras inserindo um número de rastreamento. No entanto, os usuários regulares podem se registrar para a associação para acessar recursos avançados, como prontidão de entrega e outras estatísticas. Desenvolvemos o portal de rastreamento para armazenar contas de usuário no Microsoft Entra ID.
O Microsoft Entra ID foi projetado como um sistema global por padrão. Como tal, não é vulnerável a falhas regionais, e não temos de modificar esta componente do sistema.
Armazenamento de Blobs do Azure
O conteúdo estático, como imagens e vídeos, é armazenado em contas de Armazenamento do Azure como Blobs (Objetos Grandes Binários) e servido aos usuários por meio da CDN do Azure.
Em nosso design original, a conta de armazenamento está contida em uma única região porque optamos por usar o LRS (Armazenamento Localmente Redundante). Nossos dados são replicados apenas em um único datacenter com LRS. A conta de armazenamento, portanto, não estará disponível se houver uma interrupção regional nessa configuração. Qualquer conteúdo estático já armazenado em cache pela CDN permanece disponível para os usuários.
O mesmo acontece com o ZRS (Zone Redundant Storage, armazenamento redundante de zona). Embora os dados sejam replicados para diferentes data centers nessa configuração, todos esses data centers ainda estão na mesma região. Uma interrupção regional também afeta a conta de armazenamento nessa configuração.
Em nosso projeto, dependemos muito de nossa configuração CDN para armazenar conteúdo estático em cache. Há uma chance de que, durante uma interrupção, um usuário solicite um arquivo estático que ainda não esteja no cache da CDN. Essa solicitação resultaria em um gráfico ou vídeo que não pode ser exibido.
Podemos eliminar essa possibilidade replicando a conta de armazenamento para várias regiões quando escolhemos uma opção de armazenamento com redundância geográfica. Uma opção de replicação só de leitura também está disponível para impedir a adição de conteúdo estático durante uma falha regional.
Temos duas opções para escolher quando precisamos ativar a redundância geográfica. Estas opções são Read-Access Geo-Redundant Storage (RA-GRS) e Read-Access Geo-Zone-Redundant Storage (RA-GZRS). A escolha que fazemos depende do nosso orçamento e da percentagem de tempo de atividade de que precisamos.
Serviço de Aplicativo do Azure e Aplicativos de Função do Azure
Nosso portal de rastreamento de remessas implementa dois Serviços de Aplicativo do Azure. O primeiro Serviço de Aplicativo hospeda um aplicativo Web que implementa a interface Web voltada para o usuário e o segundo hospeda uma API Web usada por aplicativos móveis para rastrear dados de remessas. Todas as nossas tarefas em segundo plano são executadas como aplicativos do Azure Function.
Em nosso design original, cada Serviço de Aplicativo do Azure é localizado em uma única região do Azure. Criamos um segundo Serviço de Aplicativo na região secundária (Oeste dos EUA) e implantamos o projeto Web lá para dar suporte à nova arquitetura multirregião. Configuramos o modo de roteamento prioritário do Azure Front Door para enviar solicitações para nossa região secundária quando a região primária não estiver disponível.
Para garantir que o failover seja o mais suave possível, certifique-se de que o aplicativo Web não armazene nenhuma informação de estado da sessão na memória. Alteramos o nosso site para garantir que não acabamos com perda de dados. Por exemplo, se nosso código armazena uma lista das remessas dos usuários na memória, essa lista será perdida se ocorrer um failover.
Cada solicitação da Web é tratada sem afetar a outra quando nenhum estado de sessão é armazenado. Se ocorrer um failover no meio da sessão de um usuário, o failover deverá ser transparente para o usuário.
Fazemos uma alteração semelhante aos nossos aplicativos do Azure Function. Criamos uma instância separada da Função do Azure na região secundária e implantamos o mesmo código personalizado que é executado na região primária.
Importante
Ao implantar uma atualização para o código personalizado no Serviço de Aplicativo ou no Serviço de Aplicativo de Função, lembre-se de distribuí-la para todas as instâncias do Serviço de Aplicativo. Se você quiser automatizar esse processo, o Azure DevOps tem ferramentas que podem ajudar.
Filas de armazenamento do Azure
Em nossa arquitetura original de região única, usamos uma fila em uma conta de Armazenamento do Azure para gerenciar as comunicações entre o Serviço de Aplicativo e o aplicativo de função. Quando o aplicativo Web ou a API da Web precisa executar uma tarefa em segundo plano, ele coloca uma mensagem com todas as informações necessárias na fila. O aplicativo de função monitora a fila de novas mensagens e executa a tarefa em segundo plano executando as consultas necessárias nos armazenamentos de dados.
Podemos gerenciar uma alta demanda em solicitações da web de forma ordenada quando usamos uma fila dessa maneira. Quando há muitas tarefas em segundo plano para executar, a fila pode se acumular, mas as tarefas não são descartadas. Eles ficam na fila até serem processados. Os aplicativos de função funcionam através da fila e reduzem seu tamanho quando a demanda cai. Se a demanda persistir, aumentamos o número de instâncias do aplicativo de função.
Para a versão multi-região do portal de rastreamento de remessas, devemos garantir que os itens da fila não sejam perdidos aquando da ocorrência de um failover. Nossa fila é definida no Armazenamento do Azure e podemos usar uma opção de redundância para replicação geográfica.
Lembre-se de que não podemos usar uma opção de redundância para acesso apenas de leitura, pois nossa fila oferece suporte a operações de leitura e gravação. O Serviço de Aplicações deve adicionar itens à fila, e a aplicação de funções deve remover os itens concluídos da fila. Em vez disso, use Geo-Redundant Storage (GRS) ou Geo-Zone-Redundant Storage (GZRS).
Azure Redis Cache
Estamos usando o Cache Redis do Azure para maximizar o desempenho do armazenamento de dados. O Redis armazena em cache todos os resultados de consulta gerados a partir de nossos aplicativos à medida que eles solicitam dados de nosso banco de dados. Quaisquer consultas adicionais para dados semelhantes não precisam de uma consulta de banco de dados e são buscadas no cache Redis.
Para a arquitetura de várias regiões, criamos uma instância de Cache Redis nas regiões primárias e de espera. Lembre-se de que, quando ocorre um failover, é provável que o Cache Redis na região de espera esteja vazio. Esse cache vazio não causa erros, mas o desempenho pode cair temporariamente, à medida que os dados preenchem o novo cache.