Execução Distribuída de JMeter (AWS Fargate + Docker)
Tabela de conteúdos
avançado - This article is part of a series.
Com este artigo concluímos a série distribuída sobre o JMeter. Neste caso, estamos usando contêineres. Há muitas variantes dessa modalidade, pois podemos usar uma grande variedade de plataformas de administração e orquestração baseadas em contêineres:
- Amazon Elastic Kubernetes Service (EKS)
- Azure Kubernetes Service (AKS)
- Google Kubernetes Engine (GKE)
- Rancher, etc.
Podemos também usar versões não-Kubernetes:
- Amazon Elastic Container Service (ECS) no AWS.amazon.com/ecs/
- Azure Container Instances (ACI) no Azure.microsoft.com/services/container-instances/
- Google Cloud Run no Google.cloud.run/ etc.
Para este exemplo específico, usaremos a solução Amazon Elastic Container Service (ECS) com o serviço Fargate.
Quando seria prudente assumir o esforço? #
Como mencionei em minhas publicações anteriores JMeter distribuído localmente e JMeter distribuído públicamente, recomendo que você use este método se precisar de uma carga ou teste sob carga entre 8.000 e 25.000 threads ou usuários virtuais. Isso ocorre porque é necessário investir tempo e esforço para permitir esse método. Claro, essa modalidade pode ser expandida muito além dos 25k threads. No entanto, recomendo usar EC2 em vez de Fargate e solicitar suporte à monitorização das instâncias e resultados em tempo real.
Como funciona? #
Esta arquitetura não funciona mais em modo mestre-servidor. O principal motivo é que o mecanismo de comunicação entre o mestre e os servidores, RMI (Java Remote Method Invocation), não é muito eficiente para volumes grandes e poderia gerar obstáculos (ironicamente). Cada contêiner executado será um gerador de carga, e para criar a imagem do contêiner, usaremos baseamos-nos na alternância da fluidez do guia JMeter + Docker.
Quando o imagem estiver disponível no repositório AWS, podemos definir uma tarefa ligada à essa imagem. Para executar, será feita via Fargate e podemos escalar até um máximo de 50 tarefas. Mas lembre-se, cada tarefa seria um contêiner ativo ou um gerador de carga, então há 50 geradores de carga disponíveis.
A execução copiará os arquivos de resultado do JTL e o log de JMeter para S3, permitindo que você baixe, processe ou archive-os como evidência da execução. Aqui está um exemplo semelhante ao que vamos seguir na próxima etapa, mas é feito através de comando linha e está em Inglês.
Receita para cozinhar #
1. Clone o Repositório #
Primeiro precisamos clonar o seguinte repositório para obter os arquivos necessários para construir nossa imagem Docker:
clone git https://github.com/daeep/JMeter_Docker_AWS.git
cd JMeter_Docker_AWS
2. Gerar a permissão IAM #
Criaremos uma permissão específica para executar tarefas no Fargate, essa permissão é chamada de ecsTaskExecutionRole. Essa permissão pode ser gerada através do comando linha de comando ou pelo console AWS Management Console. Recomendo instalar e configurar o CLI AWS CLI para criar esta permissão usando o arquivo task-execution-assume-role.json
incluído no repositório que baixamos.
aws iam --region us-east-1 create-role --role-name ecsTaskExecutionRole --assume-role-policy-document file://task-execution-assume-role.json
aws iam --region us-east-1 attach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Você pode ver que estou trabalhando na região us-east-1.
Adicione o Bucket S3 e credenciais do AWS ao Dockerfile #
Necessitamos modificar e adaptar nosso Dockerfile localizado na direção JMeter_Docker_AWS, que é parte deste projeto. Este projeto contempla salvar os arquivos de resultado em S3, embora pudéssemos também salvá-los em InfluxDB ou ElastiSearch para serem consumidos por Grafana ou Kibana, respectivamente. Para salvar os arquivos de resultado em S3, precisamos criar um bucket e incluir nossas credenciais nas linhas 18-20 do Dockerfile, essas credenciais poderiam ser as mesmas que usam o AWS CLI se você concedesse permissões de administrador ao mesmo.
18 ENV AWS_ACCESS_KEY_ID #####################
19 ENV AWS_SECRET_ACCESS_KEY #################
20 ENV AWS_DEFAULT_REGION #################### <-- can be the region (us-east-1)
Finalmente, precisamos modificar as linhas 53 e 54 com o nome da bucket onde os arquivos serão armazenados. Aqui está um guia em espanhol para criar buckets: guia. Se você não deseja salvar o arquivo JTL resultante e a bitstream do log de JMeter, precisará deletar as linhas 18-20 e 49-54. No entanto, recomendo que isso não seja feito.
53 && aws s3 cp ${JMETER_HOME}/result-${PUBLIC_IP}-${LOCAL_IP}.jtl s3://nombre-del-bucket/ \
54 && aws s3 cp ${JMETER_HOME}/jmeter-${PUBLIC_IP}-${LOCAL_IP}.log s3://nombre-del-bucket/
Construa o arquivo Docker #
Vamos compilar nossa imagem antes de pushá-la para o repositório. Podemos fazer isso executando o shell script ./build.sh localizado em nosso diretório ou usando o comando: docker build -t jmeter-docker ., que é muito semelhante ao fluxo de publicação do projeto JMeter + Docker. Este projeto também está preparado para compilar a imagem com nossos binários locais, mas agora copiará o script JMX dentro da contêiner (modifique linha 13). Se precisar de arquivos suporte como CSV ou imagens, adicione-os de forma semelhante às linhas 11, 13, 14 e 17.
11 ENV JMETER_HOME /home/jmeter <-- Carpeta local interna
...
13 ENV JMETER_SCRIPT JMeter_Docker_Script_Plugins.jmx <-- Nombre de tu script local
14 ENV JMETER_FILE ${JMETER_HOME}/${JMETER_SCRIPT} <-- Archivo final interno
...
17 COPY ${JMETER_SCRIPT} ${JMETER_FILE} <-- Copia el archivo local dentro del contenedor
5.- (Opcional) Se precisar de mais memória #
Depois que nossa imagem está compilada, podemos rodá-la localmente para validar se realmente funciona. Para isso, você pode alternar as linhas 21 ou 22, que contêm valores diferentes para JVM_ARGS. É importante notar que este script é parametrizado de acordo com as instruções descritas parâmetros. Lembre-se de recompilar antes de rodá-lo se você modificar esse valor e, por fim, para iniciar a execução podemos usar o script shell ./run.sh.
21 ENV JVM_ARGS="-Xms2048m -Xmx4096m -XX:NewSize=1024m -XX:MaxNewSize=2048m -Duser.timezone=UTC" <-- Suficiente para algunos cientos de usuarios concurrentes
22 ENV JVM_ARGS "-Xms256m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=1024m -Duser.timezone=UTC" <-- Suficiente para algunas decenas de usuarios concurrentes
6.- Crie o repositório ECS e suba a imagem Docker #
Continuamos criando um repositório AWS ECS, não é complicado. Você também pode consultar os passos aqui uma vez que você tenha o repositório pronto. Vamos subir a imagem com as seguintes instruções:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 659336004062.dkr.ecr.us-east-1.amazonaws.com
docker tag jmeter-docker:latest 659336004062.dkr.ecr.us-east-1.amazonaws.com/jmeter-docker:latest
docker push 659336004062.dkr.ecr.us-east-1.amazonaws.com/jmeter-docker:latest
Crie um Cluster Fargate #
Agora criaremos um cluster Fargate. Acredito que você possa reproduzir os passos seguindo as imagens.
Definindo Tarefas em Fargate #
Vamos definir uma nova tarefa, e creio que é possível continuar apenas com imagens.
Lembre-se de que os valores para CPU e Memória, bem como o limite gentil de memória são configuráveis e recomendo começar com alguns hilo para não rapidamente exaurir recursos e falhar na avaliação.
9. Executar Tarefas #
Finalmente, executaremos os(tas) dentro de nosso Cluster. O número máximo de tarefas por cluster é 10. Se quisermos executar mais tarefas, precisaremos gerar mais clusters. A vantagem é que o trabalho já foi definido e será muito fácil rodá-lo em múltiplos clusters. Entendo que há um limite total de 50 tarefas, o que significa 5 clusters rodando até 10 tarefas cada máximo, mas também você pode solicitar aumentos nas limites, embora se precisar de mais poder computacional, recomendo usar EC2 em vez de Fargate.
No se pode definir variáveis de ambiente no segmento de execução deste tarefa. Portanto, não é possível sobrescrever ou cancelar variáveis como usuários, rampa ou duração aqui.
Conclusão #
Entendo que há muitos passos e eles podem parecer difíceis, especialmente se você é novo em AWS ou ECS. Isso porque eu decidi publicar a seção Docker antes de explicar a seção AWS, esperando minha tentativa de simplificar o conteúdo ajudar a reproduzir isso. Este solução é extremamente versátil e poderia ser usada com qualquer outro plataforma de orquestração de contêineres para execução e obtenção de resultados semelhantes. Também deve ser notado que conseguimos resolver algumas seções usando docker-compose ou ec2_param em formato YAML via linha de comando, mas a intenção era simplificar o conteúdo. Espero que eles possam replicar essa schema sem hesitação contactando-nos caso precisem nossa ajuda.
Finalmente, deixarei você com como os arquivos ficariam no S3 e o painel Grafana com a informação deste execução.
https://jmeter-docker.s3.amazonaws.com/result-35.174.62.31-172.31.72.172.jtl