Skip to content

Pedro-Manoel/projeto-arquitetura-de-software

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📑 Projeto de Arquitetura de Software - UFCG

📝 Objetivo

📍 Geral

Analisar o comportamento de um sistema que emprega uma arquitetura de microsserviços em seu backend. O foco é entender como o sistema reage quando um ou mais de seus microsserviços recebem uma carga elevada. Especial atenção é dada à maneira como o sistema gerencia essa sobrecarga, comparando cenários com e sem a implementação de autoscaling.

📍 Específico

O objetivo é realizar um teste de carga em um sistema com arquitetura de microsserviços, observando seu comportamento e as métricas resultantes. Em seguida, o mesmo teste será aplicado ao sistema, mas desta vez em um cenário que conta com um serviço de autoscaling ativo. A comparação desses dois cenários proporcionará insights importantes sobre o desempenho do sistema sob diferentes condições.

⚙️ Sistema

🔖 Descrição

O sistema é um backend para e-commerce com API em Node.js, organizado em microsserviços encapsulados em containers Docker. Segue os princípios da Clean Architecture, com um proxy server direcionando as solicitações. Utiliza MongoDB para gestão de dados, com modelos definidos pelo Mongoose. A comunicação entre certos microsserviços é feita através do RabbitMQ e do protocolo AMQP.

O código fonte deste sistema, que foi modificado para a realização do experimento, está disponível em um artigo detalhado no Medium. Para uma compreensão mais profunda do projeto e das modificações realizadas, recomendamos a leitura deste artigo. O repositório completo do código fonte pode ser acessado aqui.

📦 Arquitetura

A arquitetura do sistema, com as modificações aplicadas, é apresentada abaixo:

Arquitetura no Docker

🪄 Experimento

🛠️ Ferramentas utilizadas

O experimento envolveu a utilização de várias ferramentas:

  • Docker - Plataforma para desenvolvimento, deploy e execução de aplicações utilizando containers.
  • Kubernetes - Sistema de orquestração de containers.
  • Kind - Ferramenta para criação de clusters Kubernetes locais.
  • Kubectl - Ferramenta de linha de comando para interagir com o cluster Kubernetes.
  • Heml - Gerenciador de pacotes para Kubernetes.
  • Make - Ferramenta para automatizar a execução de tarefas.
  • k6 - Ferramenta para testes de carga.

⚖️ Migração da aplicação para o Kubernetes

A migração completa da arquitetura do projeto, originalmente implementada no Docker, para o Kubernetes foi necessária. O Kubernetes oferece recursos avançados como Autoscaling e Load Balancer. Essas funcionalidades foram fundamentais para a decisão de migração.

📦 Arquitetura Completa

A arquitetura completa oferece uma visão detalhada de todos os componentes e como eles interagem entre si.

Arquitetura completa no Kubernetes

📦 Arquitetura Simplificada

A arquitetura simplificada fornece uma visão geral do sistema, focando nos componentes principais.

Arquitetura simplificada no Kubernetes

💡 Observações

📌 Configuração do HPA (Horizontal Pod Autoscaling) no Kubernetes

  • Limite de CPU: 70%
  • Número de réplicas mínimas: 1
  • Número de réplicas máxima: 10

📌 Configuração do teste de carga com o K6

Realizamos três testes em paralelo durante um período de 15 minutos. Cada teste focou em um microsserviço específico e usou uma quantidade diferente de usuários virtuais (VUs).

  • Microsserviço de Usuários

    • Endpoin: GET /users
    • Carga: Constante
    • Usuários Virtuais (VUs): 15
  • Microsserviço de Ordens de Compras

    • Endpoint: GET /orders
    • Carga: Constante
    • Usuários Virtuais (VUs): 10
  • Microsserviço de Produtos

    • Endpoint: GET /products
    • Carga: Variável, dividida em 3 estágios:
      • Estágio 1: 30 VUs por 5 minuto
      • Estágio 2: 60 VUs por 5 minutos
      • Estágio 3: 90 VUs por 5 minutos

🚀 Deploy da aplicação no Kubernetes

Para realizar o deploy da aplicação no Kubernetes, siga os passos abaixo:

  1. Criar o cluster Kubernetes local:

    kind create cluster
  2. Configurar o monitoramento da aplicação instalando o kube-prometheus-stack:

    make add-prometheus-stack
  3. Construir as imagens Docker dos microsserviços:

    make docker-build-all
  4. Fazer o load das imagens Docker no cluster Kubernetes (Processo demorado):

    make kind-load-docker-images
  5. Realizar o deploy da aplicação:

    make kube-up
  6. Verificar se a aplicação e o monitoramento estão funcionando corretamente. Todos os serviços devem estar com o status Running:

    6.1 Verificando aplicação

    kubectl get pods

    6.2 Verificando o monitoramento

    kubectl get pods -n monitoring

✅ Preparação do teste de carga

  1. Levantar o ambiente para a execução:
    make k6-up

⚠️ Realizar o experimento

  1. Expor o api-gateway para acesso externo:

    make kube-expose-app
  2. Expor o Grafana do Kubernetes para acesso externo:

    make kube-expose-grafana
  3. Importar o dashboard do Kubernetes no grafana:

    3.1 Acessar o grafana do Kubernetes

    3.2 Importar o dashboard Kubernetes Horizontal Pod Autoscaler

  4. Importar o dashboard do K6 no grafana:

    4.1 Acessar o grafana do K6

    4.1 Configurar a conexão com o InfluxDB:

    • URL: http://influxdb:8086
    • Database: k6

    4.2 Importar o dashboard k6 Load Testing Results

  5. Iniciar o teste de carga:

    make k6-run
  6. Acompanhar o dashboard do K6 e do Kubernetes para verificar o comportamento da aplicação e os resultados do teste.

  7. Ao finalizar o teste de carga devemos:

    7.1 Derrubar o ambiente de execução do K6:

    make k6-down

    7.2 Derrubar o ambiente de execução da aplicação:

    make kube-down

🪄 Resultados no Grafana

❌ Sem Autoscaling

Microsserviço de Usuários

Teste de carga usuários

Microsserviço de Ordens de Compras

Teste de carga ordens de compras

Microsserviço de Produtos

Teste de carga produtos

Resultados K6

Resultados K6

✅ Com Autoscaling

Microsserviço de Usuários

Teste de carga usuários

Microsserviço de Ordens de Compras

Teste de carga ordens de compras

Microsserviço de Produtos

Teste de carga produtos

Resultados K6

Resultados K6

🔍 Análise

❌ Sem Autoscaling

  • A utilização de CPU para os microsserviços de usuários e ordens de compras se manteve relativamente constante entre 40%-60% e 20%-40%, respectivamente.
  • Para o microsserviço de produtos, a utilização de CPU cresceu até 200% com a carga crescente.
  • No K6, a maioria das requisições foi bem-sucedida com uma taxa de falha de 0,00%. A média da duração da requisição foi de 222,18 ms.

✅ Com Autoscaling

  • A utilização de CPU para os microsserviços de usuários e ordens de compras se manteve relativamente constante entre 40%-50% e 20%-40%, respectivamente.
  • Para o microsserviço de produtos, a utilização de CPU cresceu até 92% com a carga crescente, depois se manteve constante entre 50% e 70%.
  • Durante o teste, apenas 5 de 10 réplicas máximas foram provisionadas, permitindo um uso de CPU variável entre 50% e 70%.
  • No K6, todas as requisições foram bem-sucedidas com uma taxa de falha de 0,90%. A média da duração da requisição foi de 125,60 ms.

❇️ Conclusão

Os resultados indicam que o autoscaling foi eficaz em manter a utilização da CPU na média desejada e resolver o problema de sobrecarga do sistema. Isso é evidenciado pela redução na utilização máxima da CPU no microsserviço de produtos de 200% para 92%. Além disso, a duração média da requisição diminuiu de 222,18 ms para 125,60 ms com o autoscaling, indicando uma melhoria no desempenho. No entanto, houve um ligeiro aumento na taxa de falha das requisições de 0,00% para 0,90% com o autoscaling. Isso pode ser um ponto a ser investigado para futuras otimizações. Em geral, o autoscaling parece ter contribuído positivamente para a gestão da carga e o desempenho do sistema.

About

🎓 Repositório com o projeto final da disciplina de Arquitetura de Software da UFCG

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published