O blog da AWS

Teste de carga para APIs na AWS usando JMeter

Por Erik Miyashita e Thiago Paulino, Arquitetos de Soluções da AWS Brasil 

 

A computação em nuvem trouxe grandes avanços em relação a escalabilidade de APIs (Application Programming Interfaces). No entanto, mesmo com a melhora na eficiência deste processo, seguimos com a necessidade de entender onde existem gargalos de desempenho nas aplicações. Para identificar esses gargalos, uma das melhores ferramentas continua a ser o teste de carga.

Recentemente foi desenvolvida uma solução da AWS para este fim, tornando o processo de configuração de um teste de carga na AWS muito mais fácil. Trata-se de uma arquitetura que utiliza o AWS Fargate e o framework Taurus como injetores de carga.

Antes de executar qualquer teste de carga na AWS, lembre-se de reler a política para testes de carga descrita aqui.

Outro aspecto relevante a se avaliar antes de utilizar a solução são os limites. Conforme a documentação da solução, o por região, enquanto o container concorrentes por task. Portanto o limite máximo para o teste será de 50 x 200 = 10.000 requisições concorrentes.

A solução desenvolvida permite que você realize testes diretamente em um endpoint, sem a necessidade de criação de scripts. No entanto, sabemos que nem sempre o cenário a ser testado é simples, e quase sempre é necessário criar um script em uma ferramenta de testes de carga. Neste blogpost vamos ir um pouco além da solução padrão e utilizaremos o Apache JMeter como ferramenta para a criação dos scripts de teste.

Em alto nível, a solução utiliza o framework de teste Taurus sendo executado pelo AWS Fargate, gerando resultados dentro do S3 e métricas no CloudWatch. A arquitetura da solução pode ser vista abaixo:

 

 

O framework de Continuous Testing Taurus nos permite que sejam executados scripts de Selenium, JMeter entre outros. Se o seu script foi feito usando outra tecnologia, verifique o suporte no do projeto T. Neste blogpost iremos nos concentrar em um cenário com um script de JMeter.

 

Etapa 1: Criação do script de teste no Apache JMeter

 

 

Neste  blogpost utilizamos a versão 5.3 do Apache JMeter. Ele será útil para a criação do script de teste.

Dentro do JMeter, crie uma estrutura de Grupo de Usuários e abaixo dele, um HTTP request. Na imagem acima, indicamos o endpoint da API que receberá o teste. Além deste dado, também informamos o path da request (/prod/pets, neste caso). Caso o seu teste necessite de múltiplas requisições, adicione novos HTTP requests e configure cada um deles. Adicione também uma Result Tree – ela nos ajudará a validar o script criado. Depois de tudo ajustado, realizamos um teste inicial, apenas com o objetivo de validar o script usando o comando Run > Start. Caso o script do JMeter esteja funcionando como esperado, poderemos observar as respostas HTTP no Result Tree, conforme a imagem abaixo.

 

 

Caso o script esteja adequado ao seu teste, podemos salvar o teste com a extensão .jmx. Este script criado no JMeter será utilizado pela solução de testes de carga. Vejamos como configurar a próxima etapa, quando ajustamos os arquivos de configuração do teste.

 

Etapa 2: Deploy da solução de teste de carga

A solução de teste de carga disponibilizada pela AWS pode ser encontrada neste endereço. O deployment por meio de um documento de CloudFormation. Com este documento é possível instalar a solução com apenas alguns cliques. Na página da solução, execute o deployment do cloudformation. Você será direcionado para a configuração do serviço:

 

 

Verifique se está configurando a solução na região desejada. Na página seguinte da configuração, são ajustados parâmetros de rede e de acesso. Tome nota do nome de usuário e do email que você configurou – depois do deployment do cloudformation será enviado um email para você com a senha de acesso da console do teste.

Observe também que é possível configurar a VPC e as subnets do AWS Fargate. Leve em consideração este ponto na sua arquitetura – principalmente do ponto de vista de roteamento de rede, já que o volume de requisições do teste tem como origem essas subnets e o Fargate deverá conseguir acessar a sua aplicação. O cloudformation realiza a criação de VPC para o teste, por isso verifique também se o seu limite de conta. Existem limites de criação de VPCs por conta, caso o seu limite esteja próximo, siga as orientações de nossa documentação de VPC’s e solicite aumento dessa cota link.

 

 

Depois de todas as configurações, você será direcionado para a página de resumo da configuração. Marque a opção de criação de Role IAM e inicie o stack:

 

 

O deployment do cloudformation pode demorar alguns minutos. Após concluir, você pode verificar o endpoint de acesso à solução na aba Outputs, no campo Console:

 

 

Ao acessar a console da solução, você deverá utilizar o usuário e senha recebidos por email após o deployment do cloudformation. Neste ponto temos a solução de teste de carga criada dentro da sua conta AWS. Todos os elementos da arquitetura mostrados no início deste artigo foram criados automaticamente pelo cloudformation. O próximo passo agora é configurar a solução para utilizar o script JMeter que criamos na etapa 1.

 

Etapa 3: Configurar o cenário de teste

 

 

Atualmente, a solução Distributed Load Testing realiza o teste somente em um endpoint diretamente, portanto vamos customizar a solução para podermos utilizar o nosso script de JMeter. Faremos isso seguindo os seguintes passos:

-Clone do repositorio da solução em:  https://github.com/awslabs/distributed-load-testing-on-aws

 

$ git clone https://github.com/awslabs/distributed-load-testing-on-aws.git 

-Copie o seu script de teste (.jmx) para a pasta /source/container/

-Crie um arquivo de configuração do teste. Neste exemplo usamos teste.json. Este arquivo define quantidade de transações, o arquivo de script do jmeter, think time, tempo de R do teste, timeouts de scenarios, reporting e outras configurações. Caso queira customizar este arquivo, utilize a documentação do Taqui.

 

teste.json

{
"execution": [{
"concurrency": "50",
"ramp-up": "2m",
"hold-for": "5m",
"scenario": "Primeiro"
}],
"scenarios": {
"Primeiro": {
"script": "APIGW_Pets.jmx",
"timeout": "5s",
"think-time": "1s"
}
},
"reporting": [{
"module": "final-stats",
"summary": true,
"percentiles": true,
"summary-labels": true,
"test-duration": true,
"dump-xml": "/tmp/artifacts/results.xml"
}]
}

 

-Ajuste o arquivo /source/container/load-test.sh para incluir o seu arquivo de configuração do teste. (teste.json neste caso)

 

load-test.sh

# set a uuid for the resultsxml file name in S3
UUID=$(cat /proc/sys/kernel/random/uuid)

echo "S3_BUCKET:: ${S3_BUCKET}"
echo "TEST_ID:: ${TEST_ID}"
echo "UUID ${UUID}"

echo "Download test scenario"
# aws s3 cp s3://$S3_BUCKET/test-scenarios/$TEST_ID.json test.json
:
echo "Running test"
bzt teste.json -o modules.console.disable=true

t=$(python -c "import random;print(random.randint(1, 30))")
echo "sleep for: $t seconds."
sleep $t

echo "Uploading results"
aws s3 cp /tmp/artifacts/results.xml s3://$S3_BUCKET/results/${TEST_ID}/${UUID}.xml

-Ajuste o arquivo /source/container/Dockerfile  incluir seus arquivos de script e configuração do teste.

 

FROM blazemeter/taurus
# taurus includes python and pip
RUN pip install —no-cache-dir awscli
# Taurus working directory = /bzt-configs
ADD ./load-test.sh /bzt-configs/

ADD ./APIGW_Pets.jmx /bzt-configs/ #Seu script do JMeter
ADD ./teste.json /bzt-configs/ #Seu arquivo de configuracao do teste

RUN chmod 755 /bzt-configs/load-test.sh
ENTRYPOINT ["sh", "-c","./load-test.sh"]

 

-Na sua linha de comando, faça o push das novas configurações do container para o ECR. Para visualizar os comandos, acesse o serviço Elastic Container Registry na sua console AWS. Clique em View e execute os 4 comandos (login, build, tag, push). Isto iniciará o deployment de uma nova versão do container do Taurus, agora com os novos arquivos de configuração que criamos para o teste. Em background, os serviços AWS CodePipeline e AWS CodeBuild identificam a alteração e submetem uma nova versão do container.

 

 

Etapa 4: Executar o teste

Depois de criar uma nova versão do container Taurus, estamos prontos para executar o teste. Perceba que durante a configuração anterior, criamos um novo arquivo de configuração do teste, portanto as que existem na console da solução serão ignoradas. Utilize a interface abaixo e crie um teste usando valores fictícios. Relembrando: estes valores já estão dentro do seu arquivo de configuração criado na etapa 3.

 

 

Após a criação do teste, verifique que uma nova Task foi criada dentro do Fargate. Esta tarefa instanciará o container criado na etapa 3 e iniciará o teste de carga.

 

 

Durante a execução do teste você pode acompanhar algumas métricas dentro da console da solução, como visto abaixo:

 

 

Etapa 5: Monitorar a execução do teste e analisar resultados

Após a execução do teste, é possível avaliar os impactos da simulação de usuários utilizando o AWS CloudWatch. No cenário abaixo, adicionamos as métricas do API Gateway (nosso endpoint-alvo do teste): Contagem de requisições, Latência de integração, Número de erros 4xx e 5xx e Latência. Acompanhando estas métricas é possível identificar problemas de tempo de resposta e caso seja necessário, pode-se avaliar os logs gerados dentro do CloudWatch Logs.

 

 

Conclusão

Com a ajuda da solução “Distributed Load Testing” explicamos neste blogpost como criar um script JMeter, como criar uma nova versão do container Taurus e o teste de carga em uma API na AWS. No caso explicado aqui, utilizamos um script do JMeter que pode conter multiplas requisições. Em casos de testes mais simples, com objetivo de testar apenas um endpoint, pode se ignorar a etapa 3 explicada aqui e utilizar diretamente a console da solução para executar o teste, o que torna a execução ainda mais simples.

Em relação a análise e monitoração do seu backend, existem outras formas de avaliar o desempenho da aplicação, como por exemplo a utilização de ferramentas de APM (Application Performance Management). Este tipo de monitoração é capaz de identificar questões de desempenho dentro das camadas da aplicação e infraestrutura, indicando possíveis pontos de gargalo da aplicação.

Realizar testes de carga é uma tarefa que segue sendo importante mesmo em aplicações de API cloud-native. Com este tipo de teste é possível avaliar possíveis gargalos de desempenho antes de usuários reais serem afetados.

 

 


Sobre os Autores

Erik Miyashita é Arquiteto de Soluções na AWS com larga experiência em sistemas distribuídos, DevOps e monitoração. Atualmente atende clientes do segmento enteprise, auxiliando-os a utilizar melhor os recursos de cloud computing.

 

 

 

Thiago Paulino é Arquiteto de Soluções da AWS com mais de 15 anos de experiência e especialização em BigData & Analytics. Atualmente seu foco está no suporte a clientes do segmento enterprise.