Este artigo resume o processo e os componentes que a equipe de Engenharia de Software Comercial (CSE) da Microsoft usou para criar uma solução para um cliente bancário. Por uma questão de anonimato, o artigo refere-se ao cliente como Contoso Bank. É uma grande organização da indústria internacional de serviços financeiros (FSI) que queria modernizar um de seus sistemas de transações financeiras.
Arquitetura
Transfira um ficheiro do Visio desta arquitetura.
Três blocos principais compõem a solução: serviços de back-end, teste de carga e monitoramento com o Event Autoscaler.
Os contêineres de microsserviços reais da Contoso foram enviados manualmente pelo Docker para o cluster do Kubernetes. Este cluster foi:
Azure Red Hat OpenShift (ARO) no Kubernetes/OpenShift Horizontal Pod Autoscaler (HPA) para:
Porta-canais.
Escalabilidade e desempenho para entregas de simulação de transações.
Serviço Kubernetes do Azure (AKS) para o autoscaler do nó para Channel Holder.
A equipe CSE criou os outros microsserviços como stubs para isolar especificamente os microsserviços reais da Contoso de outros serviços de mainframe externos que a solução enviou por meio dos Pipelines do Azure.
Fluxo de Trabalho
No núcleo, os serviços de back-end fornecem a lógica necessária para que um EFT aconteça:
Um novo EFT começa com uma solicitação HTTP recebida pelo serviço Channel Holder.
O serviço fornece respostas síncronas aos solicitantes usando um padrão de publicação-assinatura por meio de um Cache Redis do Azure e aguarda uma resposta de back-end.
A solução valida essa solicitação inicial usando o serviço EFT Pilot Password.
Além de realizar validações, o serviço também enriquece os dados. O enriquecimento de dados ajuda o back-end a decidir se a solução deve usar um sistema de microsserviço herdado ou um novo para processar o EFT.
Em seguida, o serviço Channel Holder inicia o fluxo assíncrono.
O serviço chama o controlador EFT, que é um orquestrador reativo que coordena um fluxo de transação. Ele faz isso produzindo comandos e consumindo eventos de outros microsserviços por meio dos Hubs de Eventos do Azure/Kafka.
Um desses serviços é o EFT Processor, onde a solução efetua a transação real, realizando operações de crédito e débito.
A equipe CSE usou o Kubernetes Event-driven Autoscaling (KEDA). É uma estrutura que dimensiona automaticamente os aplicativos com base na carga de mensagens processada pela solução. Na solução, ele foi usado para dimensionar o processador EFT à medida que a solução processava novos EFTs.
O KEDA é suportado no AKS e nos Aplicativos de Contêiner do Azure
O próximo é o teste de carga. O Teste de Carga do Azure é um serviço de teste de carga totalmente gerenciado que permite gerar carga de alta escala. O serviço simula o tráfego para seus aplicativos sem a necessidade de implantar recursos adicionais. O Teste de Carga do Azure também vem com a capacidade de pegar um script Apache JMeter existente e usá-lo para executar um teste de carga.
Finalmente, o monitoramento foi responsável pela integração de resultados de testes de carga, infraestrutura e métricas de aplicativos.
A equipe correlacionou uma execução de teste de carga com os efeitos colaterais causados por microsserviços na camada de armazenamento e orquestração de contêineres. Ele permitiu um ciclo de feedback rápido para ajuste de aplicativos. Prometheus, Grafana e Application Insights no Azure Monitor foram os principais componentes que permitiram esse recurso de monitoramento e observabilidade. O Event Autoscaler deu suporte à validação de um cenário em que os aplicativos são dimensionados com base no carregamento de mensagens recebidas. Para implementar esse comportamento, a equipe CSE adaptou o KEDA para suportar o dimensionamento de aplicativos Java.
Recursos da solução
A solução envolve três recursos principais:
Autoscaler de pod horizontal para suporte de canal
Dimensionamento automático de nó para suporte de canal
Escalabilidade e desempenho para resultados finais de simulação de transações
Autoscaler de pod horizontal para suporte de canal
Nesta solução, a equipe usou um mecanismo Kubernetes/OpenShift HPA. A HPA dimensiona automaticamente o número de pods com base em uma métrica selecionada. Isso proporciona um mecanismo eficiente de entrada e saída de contêineres. Dada a natureza vinculada à CPU da API REST do Channel Holder, a equipe optou por usar HPA com CPU para que as réplicas de serviço possam crescer à medida que novos EFTs ocorrem.
Este componente executa um serviço chamado Channel Holder no Azure Red Hat OpenShift. Realiza testes de dimensionamento automático de pods neste serviço. O componente tinha que atingir as seguintes capacidades:
Forneça um pipeline de DevOps do local para o Azure para o serviço Channel Holder.
Forneça monitoramento de cluster OpenShift por meio de um painel do Grafana.
Execute testes de Autoscaling de Pod Horizontal para o serviço Channel Holder.
Forneça observabilidade no Channel Holder ativando a captura de métricas (por exemplo, uso) com Prometheus e Grafana.
Forneça um relatório detalhado sobre os testes executados, o comportamento dos aplicativos e as estratégias de particionamento Kafka, se houver.
Dimensionamento automático de nó para suporte de canal
Primeiro, o HPA dimensiona as réplicas até um ponto em que satura a infraestrutura do cluster. Em seguida, um mecanismo de expansão para os nós mantém os aplicativos recebendo e processando novas solicitações. Para esse mecanismo, a equipe usou o dimensionamento automático do nó do Kubernetes, o que permitiu que o cluster crescesse mesmo quando todos os nós estivessem próximos de sua capacidade total.
Este componente se concentra na execução do serviço Channel Holder no AKS para permitir testes de dimensionamento automático de nós. Tinha de atingir as seguintes capacidades:
Forneça monitoramento de cluster AKS por meio de um painel do Grafana.
Execute testes de dimensionamento automático de nó para o serviço Channel Holder.
Forneça observabilidade no Channel Holder ativando a captura de métricas com Prometheus e Grafana.
Forneça um relatório detalhado sobre os testes executados, o comportamento dos aplicativos e as estratégias de particionamento Kafka, se houver.
Escalabilidade e desempenho para resultados finais de simulação de transações
Usando a estrutura de teste de carga, a equipe CSE gerou carga suficiente para acionar mecanismos de dimensionamento automático de nós e HPA. Quando a solução acionou os componentes, gerou métricas de infraestrutura e aplicativos para que a equipe validasse os tempos de resposta de escalonamento do Channel Holder e o comportamento do aplicativo sob alta carga.
Este componente se concentra na execução dos serviços Channel Holder, EFT Controller e EFT Processor no ARO e AKS. Além disso, realiza o dimensionamento automático de pods e nós e testes de desempenho em todos os serviços. Tinha de atingir as seguintes capacidades:
Execute testes de desempenho nos microsserviços até atingir ou ultrapassar 2000 transações por segundo.
Execute testes de dimensionamento automático de pod/nó horizontal nos microsserviços.
Forneça observabilidade no Channel Holder ativando a captura de métricas com Prometheus e Grafana.
Fornecer um relatório detalhado sobre os testes executados, o comportamento dos aplicativos e as estratégias de particionamento Kafka adotadas.
Componentes
A lista abaixo resume as tecnologias que a equipe CSE usou para criar essa solução:
Azure
Terceiros
É open-source
Detalhes do cenário
O Contoso Bank é uma importante organização do setor de serviços financeiros internacionais (FSI) que queria modernizar um de seus sistemas de transações financeiras.
O Contoso Bank queria usar aplicativos simulados e reais e cargas de trabalho existentes para monitorar a reação da infraestrutura da solução para escalabilidade e desempenho. A solução tinha de ser compatível com os requisitos do sistema de pagamentos existente.
Potenciais casos de utilização
O Contoso Bank queria usar um conjunto de simulações para:
Determine o impacto da escalabilidade da infraestrutura.
Determine a reação a falhas no projeto de arquitetura existente de software de mainframe específico.
A solução proposta utilizaria uma aplicação virtual para simular cenários funcionais. O seu objetivo seria monitorizar o desempenho e a escalabilidade da infraestrutura. O objetivo foi determinar o impacto de falhas nas cargas de trabalho do sistema de Transferência Eletrônica de Fundos (EFT) do mainframe por meio desse conjunto de simulações.
Também havia um requisito para propor uma transição suave de DevOps do local para a nuvem. A transição teve de incluir o processo e a metodologia do banco, e teve de utilizar as ferramentas existentes do Contoso Bank. O uso de tecnologias existentes reduziria o impacto de aprimoramento de habilidades para os desenvolvedores. A transição ajudaria o Contoso Bank a rever as decisões de design atuais e futuras. A transição também forneceria confiança de que o Azure é um ambiente robusto o suficiente para hospedar os novos sistemas distribuídos.
Considerações
Critérios de êxito
A equipe da Contoso e a equipe CSE definiram os seguintes critérios de sucesso para esse compromisso:
Critérios gerais
O Contoso Bank considerou os seguintes pontos gerais como critérios bem-sucedidos em todos os componentes:
Forneça à equipe técnica da Contoso a capacidade de aplicar a transformação digital e a adoção da nuvem. A equipa CSE:
Forneceu as ferramentas e os processos necessários no Azure.
Demonstrado como a equipe técnica da Contoso poderia continuar usando suas ferramentas existentes.
Cada componente viria acompanhado de um documento que abrangesse:
Resultados de testes de escalabilidade e desempenho.
Parâmetros e métricas considerados em cada teste.
Qualquer alteração de código ou infraestrutura, se necessário, durante cada teste.
Lições aprendidas sobre ajustes de desempenho, ajuste de desempenho e parâmetros considerados para cada teste.
Lições aprendidas e orientação sobre estratégias de particionamento de Kafka.
Recomendações/orientações gerais de arquitetura com base nos aprendizados sobre os resultados.
Critérios de entrega
Métrica | Valor (intervalo) |
---|---|
Capacidade de executar testes de dimensionamento automático de pod no Channel Holder | Destino: O sistema cria automaticamente uma nova réplica do pod Channel Holder depois de atingir 50% de uso da CPU. |
Capacidade de executar o dimensionamento automático do nó com base no Channel Holder | Destino: O sistema cria novos nós do Kubernetes devido a restrições de recursos em pods (por exemplo, uso da CPU). O Kubernetes restringe o número de nós que o sistema pode criar. O limite de nós é de três nós. |
Capacidade de executar o dimensionamento automático de pod/nó e testes de desempenho em simulação de EFT | Destino: O sistema cria automaticamente novas réplicas de pod para todos os serviços. A replicação ocorre depois de atingir 50% de uso da CPU e a criação de um novo nó do Kubernetes relacionado às restrições de recursos da CPU. A solução deve suportar 2000 transações por segundo. |
Solução técnica
A solução fornecida pela equipe incluiu preocupações transversais e implementações específicas para atingir os resultados pretendidos. Ele também teve que aderir a algumas restrições de design com base nas políticas do Contoso Bank.
Vale a pena observar que, devido a uma restrição de recurso no Azure Red Hat OpenShift 3.11, a Contoso solicitou o uso do Serviço Kubernetes do Azure para testar cenários de dimensionamento automático de nós.
Havia uma série de restrições de design que a equipe CSE teve que considerar:
Devido a requisitos internos, o Contoso Bank solicitou o uso das seguintes tecnologias:
OpenShift 3.11 como plataforma de orquestração de contêineres.
Java e Spring Boot para desenvolvimento de microsserviços.
Kafka como a plataforma de streaming de eventos com recurso Confluent Schema Registry.
A solução tinha de ser agnóstica em relação à nuvem.
As ferramentas de DevOps e monitoramento tinham que ser as mesmas que a Contoso já usava em seu ambiente de desenvolvimento local.
A solução não pôde compartilhar o código-fonte que a Contoso hospeda no ambiente local com ambientes externos. A política da Contoso só permite mover imagens de contêiner do local para o Azure.
A política da Contoso restringe a capacidade de um pipeline de integração constante (CI) funcionar entre ambientes locais e qualquer nuvem. A Contoso implantou manualmente todo o código-fonte hospedado no ambiente local, como imagens de contêiner, no Registro de Contêiner do Azure. A implantação no local era de responsabilidade da Contoso.
O cenário simulado para testes tinha que usar um subconjunto de cargas de trabalho EFT de mainframe como referência de fluxo.
O Contoso Bank teve que fazer todos os testes de HPA e desempenho no ARO.
Preocupações transversais da solução
Transmissão de mensagens
A equipe do CSE decidiu usar o Apache Kafka como a plataforma de streaming de mensagens distribuídas para microsserviços. Para uma melhor escalabilidade, a equipe pensou em usar um grupo de consumidores por microsserviço. Nessa configuração, cada instância de microsserviço é uma unidade de escala para dividir e paralelizar o processamento de eventos.
Eles usaram uma fórmula para calcular o número ideal estimado de partições por tópico para suportar a taxa de transferência estimada. Para obter mais informações sobre a fórmula, consulte Como escolher o número de tópicos ou partições em um cluster Kafka.
Velocidade CI/CD
Para DevOps, o Contoso Bank já usava uma instância local do GitLab para seu repositório de código. Eles criaram pipelines de integração contínua e entrega contínua (CI/CD) para ambientes de desenvolvimento usando uma solução personalizada baseada em Jenkins que eles desenvolveram internamente. Não estava fornecendo uma experiência de DevOps ideal.
Para oferecer uma experiência de DevOps aprimorada para a Contoso, a equipe CSE usou o Azure Pipelines no Azure DevOps para gerenciar o ciclo de vida do aplicativo. O pipeline de CI é executado em cada solicitação pull, enquanto o pipeline de CD é executado em cada mesclagem bem-sucedida para a ramificação principal. Cada membro da equipe de desenvolvimento era responsável por gerenciar os repositórios e pipelines para cada serviço. Eles também tiveram que impor revisões de código, testes de unidade e linting (análise estática do código-fonte).
A equipe CSE implantou serviços simultaneamente sem interdependência e usou agentes Jenkins conforme solicitado pelo Contoso Bank.
Eles incorporaram o Prometheus como parte da solução para monitorar os serviços e o cluster. Além de gerar dados significativos para a solução, o Contoso Bank pode usar o Prometheus no futuro para aprimorar os produtos com base no uso diário. Um painel do Grafana exibe essas métricas.
Estratégia de implementação
A equipe implementou a solução no ambiente de desenvolvimento por meio do Azure Pipelines. Cada serviço tinha seu próprio pipeline de compilação e implantação. Eles usaram um pipeline de implantação que pode ser acionado manualmente. Ele deve forçar uma implantação completa do ambiente e dos contêineres em uma versão de ramificação específica.
A equipe CSE criou ramificações de versão que geraram versões estáveis para implantação. A fusão de ramificações na ramificação principal só ocorre quando a equipe tem certeza de que está pronta para implantar a solução. Uma estratégia de reversão, além de implantar a versão estável anterior, estava fora do escopo desse engajamento. Existem portas de aprovação para cada etapa. Cada portão solicita aprovação de implantação.
Recuperação após desastre
A solução usa scripts Terraform e Azure Pipelines para todos os serviços. Se ocorrer um desastre, o Contoso Bank poderá recriar todo o ambiente usando scripts Terraform ou executando o pipeline de liberação novamente. A Terraform entende que o ambiente mudou e o recria. A solução provisiona e destrói dinamicamente a infraestrutura no Azure conforme necessário. As contas de armazenamento são ZRS (armazenamento com redundância de zona). Uma estratégia de backup estava fora do escopo desse compromisso.
Segurança e privacidade
Um registro privado (Azure Container Registry) armazenou todas as imagens de contêiner.
A solução usa segredos ARO e AKS para injetar dados confidenciais em pods, como cadeias de conexão e chaves.
O acesso ao servidor de API do Kubernetes requer autenticação através do Microsoft Entra ID para ARO e AKS.
O acesso ao Jenkins requer autenticação através do Microsoft Entra ID.
Conclusões
No final do projeto, a equipe do CSE compartilhou os seguintes insights:
Solução e resultado do compromisso
A equipe observou um alto nível de compatibilidade entre AKS e ARO para implantação de serviços.
O Application Insights Codeless facilita a criação de observabilidade, colaborando para a adoção da nuvem em migrações de elevação e mudança.
O teste de carga é uma parte importante das soluções pretendidas em grande escala e requer análise e planejamento prévios para considerar as especificidades do microsserviço.
O potencial de teste de carga para encontrar efeitos colaterais de microsserviços é frequentemente subestimado pelos clientes.
A criação de um ambiente de teste pode exigir uma estratégia de eliminação de infraestrutura para evitar custos desnecessários com a infraestrutura.
Principais aprendizagens
Há uma migração suave de aplicativos de ARO para AKS.
O recurso de dimensionamento automático do nó não estava disponível no Red Hat OpenShift versão 3.11, que foi a versão usada durante o engajamento. Como tal, a equipe CSE realizou cenários de teste de dimensionamento automático de nós através do AKS.
O fim da vida útil de um produto pode exigir personalizações criativas. Uma fase de preparação desempenha um papel importante quando a equipe entrega uma solução bem-sucedida.
Na criação deste artigo, a equipe CSE criou uma solução de teste de carga integrando instâncias de contêiner e JMeter em um pipeline de DevOps do Azure. Desde então, o Teste de Carga do Azure foi disponibilizado como um serviço de teste de carga totalmente gerenciado sem a necessidade de implantar recursos de computação adicionais.
A equipe recomendou o uso dos hubs de eventos do Azure para Kafka, mas para o Contoso Bank, o registro de esquema era um recurso importante. Para atender ao Contoso Bank no prazo solicitado, a equipe teve que considerar o uso do registro de esquema em outra instância do AKS.
O protocolo Kafka com o Schema Registry não foi suportado pelo Event Hubs Scaler no KEDA.
Próximos passos
Dimensionamento automático de aplicativos Java com KEDA usando Hubs de Eventos do Azure: exemplo de KEDA para Java
Padrão: Saga: Informações sobre o padrão Saga em Microservices.io
Recursos relacionados
Para obter mais detalhes sobre os processos e tecnologias usados para criar essa solução, consulte os seguintes artigos: