Testes de Carga com JMeter

Publicado por Jean Holderbaum no dia dev

Ways

Hoje temos mais de 4 mil clientes usando o RDStation, dessa forma, antes de realizar mudanças que podem impactar o produto, precisamos simular cargas semelhantes ao sistema em tempo real para avaliar a aceitabilidade e as opções antes de colocar em produção. Recentemente cogitamos remover o cache de um dos nossos endpoints, para avaliarmos a eficácia desse cache antes de tomarmos alguma ação, foi criado um benchmark para simular múltiplos usuários interagindo com o endpoint. Essa simulação aconteceu com a ferramenta JMeter, que é o assunto deste post em questão.

Para que servem os testes de carga?

Os testes de carga servem para avaliar e validar os limites operacionais de processamento de um software, simulando um ambiente real, considerando o tempo de transferência de dados e o tempo de resposta da transação. Além disso, é um aliado na elaboração de métricas mais conscientes, junto de ferramentas mais profissionais como o JMeter, que disponibiliza diversos recursos para a elaboração de planos de teste, sejam eles complexos ou não.

Nossos testes no endpoint foram realizados em um plano simulando 100 usuários logados simultaneamente, onde cada usuário dispara 100 requisões com intervalos de 5 segundos.

JMeter: uma ferramenta opensource para testes de carga

O JMeter é uma ferramenta opensource, desenvolvida para criar e executar testes de carga em serviços computacionais. Para a elaboração dos planos de teste, o JMeter pode te ajudar em:

  • Configurar diversos tipos de requisições
  • Criar loops e condições lógicas para cada requisição
  • Importar dados para o plano através de arquivos csv (usuários, senhas)
  • Configurar paralelismo através do número de threads, a quantidade de execução de cada thread e o intervalo entre cada uma
  • Criar testes mais eficientes simulando múltiplos usuários e requisições independentes
  • Simular um ataque ao seu servidor
  • Apresentar o resultados do teste de várias formas (em árvore, tabela)

Instalando a ferramenta

Para a instalação basta fazer o download do JMeter e descomprimir o arquivo. Na estrutura de pastas do software, temos a pasta bin onde estão os executáveis: jmeter.bat para sistemas Windows e jmeter.sh para Linux.

Componentes básicos

O JMeter permite fazer uma série de configurações para a estruturação do plano de teste. Veja na imagem os gerenciadores básicos do plano na ferramenta:

Plano de Teste

Plano de teste

O plano de teste é um container para execução de testes, definindo o que e como vai ser testado. Um plano é composto por um ou vários elementos, como podemos ver na imagem acima, cada linha abaixo do Plano de Teste é um elemento seu, tais como grupos de thread, controladores lógicos e elementos de configuração. Ao abrirmos o JMeter, um plano padrão de exemplo é sugerido, pronto para ser adaptado para suas necessidades.

Adicionando elementos de configuração

O primeiro elemento que iremos adicionar é o Padrões de Requisição HTTP (HTTP Request Defaults), que define valores padrões para as requisições HTTP. Para adicionarmos o elemento, basta clicar com o botão direito do mouse em cima do Plano de Teste em seguida em Adicionar > Elementos de configuração > Padrões de Requisição HTTP.

Padrões de Requisição HTTP (HTTP Request Defaults)

Neste elemento de configuração podemos definir os valores padrões das requisições HTTP que serão adicionadas posteriormente ao teste, como o endereço e a porta. Com este elemento, não é preciso repetir as informações que são padrão em todos os elementos de requisição HTTP. Abaixo, o elemento com as informações adicionadas.

Padrões de Requisição HTTP

Caso seja necessário, também pode ser feita configuração para servidor proxy.

Padrões de Requisição HTTP - Proxy

Gerenciador de Cookie HTTP (HTTP Cookie Manager)

O gerenciador de cookies possibilita o uso de cookies no plano de teste, no nosso plano, foi necessário para manter a sessão do usuário autenticado entre as requisições. Algumas configurações podem ser alteradas, como a Política de Cookie, Implementação e a opção de Limpar cookies a cada iteração, que limpa os cookies a cada iteração do Grupo de Usuários.

Gerenciador de Cookie HTTP

Configuração de Conjunto de Dados CSV (CSV Data Set Config)

Este elemento de configuração permite a leitura de arquivos CSV e a atribuição desses dados em variáveis do JMeter que podem ser utilizadas durante o teste, como dados de login de usuários. O arquivo txt deve estar salvo no mesmo local que o arquivo do plano de teste.

Configuração de Conjunto de Dados CSV

Grupo de usuários (Thread Group)

O thread group é o início de qualquer plano de teste, é abaixo dele que ficarão todos os controladores e testadores do plano.

Nele podemos estabelecer configurações como: número de usuários (threads), tempo de intervalo para cada usuário (ramp-up period) e o número de vezes que o teste será executado (loop count).

Grupo de usuários

Requisição HTTP (HTTP Request)

A requisição HTTP é o elemento principal de um plano de teste para um sistema web, podendo existir um ou vários no mesmo plano. Nele podemos definir o verbo que será utilizado (POST, GET, PUT, etc.), enviar parâmetros com a requisição, como por exemplo o email e senha de um usuário em um POST, entre outros que serão comentados logo em seguida. Abaixo temos a imagem do elemento de requisição que utilizamos para fazer o GET na página de Login.

Requisição HTTP - GET Login

Atributos para Configuração:

  • Nome (Name): Use o nome para lembrar qual a responsabilidade do elemento. Exemplo: “Pedir novo email de senha” ou “fazer login”.

  • Nome do Servidor ou IP (Server Name or IP): Endereço ou IP do site que será testado, por exemplo: meusite.com.br. Caso você não tenha configurado o valor default anteriormente nos Padrões de Requisição HTTP, o HTTP Request irá utilizar a informação deste elemento.

  • Número da Porta (Port Number): Aqui deve ser especificado a porta que o servidor responde, caso não seja a porta 80, como por exemplo quando rodamos o server de um app rails localmente, a porta poderia ser alterada para 3000.

  • Protocolo (Protocol): O protocolo default é o HTTP, mas pode ser sobreescrito caso seja necessário o uso do protocolo HTTPS.

  • Método (Method): Caso a requisição esteja realizando alguma solicitação, o protocolo GET deve ser mantido, mas se você estiver enviando dados possivelmente vai precisar de um POST ou PUT, ou se estiver apagando, um DELETE.

  • Codificação do Conteúdo (Content Encoding): Esse atributo estabelece o formato de codificação dos dados que são enviados junto da requisição, por default esse formato é o UTF-8, mas pode ser alterado conforme suas necessidades.

  • Caminho (Path): O caminho é a página que será acessada, complementando o nome do servidor ou IP. Por exemplo em uma requisição de POST para efetuar um login, poderíamos estabelecer o caminho para /login.

  • Enviar Parâmetros com a Requisição (Send parameters with request): Aqui podem ser adicionados os parâmetros que devem ser enviados juntos do request, especificando o nome e seu respectivo valor, como mostra a imagem abaixo, onde a requisição efetua o login de um usuário através de um POST enviando o email e senha, além do token para autenticação do request. Os valores nessa requisição são de variáveis do JMeter criadas durante a execução do plano, como USER e PASSWORD que foram criadas naquele elemento de configuração para Dados CSV, que adicionamos anteriormente para fazer a leitura de um arquivo txt.

    Requisição HTTP - Parâmetros

Extractor de Expressão Regular (Regular Expression Extractor)

Este elemento pode ser utilizado para obter dados de uma página através de expressões regulares, estes dados são atribuídos à variáveis que podem ser utilizadas em outras etapas do plano posteriormente.

Extractor de Expressão Regular

Neste exemplo estamos extraíndo o token de autenticação da requisição GET feita na página de login e salvando em uma variável chamada TOKEN, a qual é utilizada na requisição POST comentada aqui em cima, que efetua o login do usuário enviando os seus dados.

Controlador de Iteração (Loop Controller)

O Loop Controller fará com que os elementos contidos dentro do Controlador executem quantas vezes o Contador de Iteração especificar, ou, para sempre, caso o check-box Infinto for marcado. Em seguida, temos a imagem que mostra o controlador no plano, com um elemento de request HTTP inserido. Isso faz com que o request GET campaigns execute 100 vezes para cada usuário, ou seja, para cada Thread Group.

Controlador de Iteração

Formato para visualização de Resultados

O elemento para visualização dos resultados pode ser adicionado clicando com o botão direito no Plano de Teste em seguida Adicionar > Ouvinte > Ver Resultados em Tabela ou Ver Árvore de Resultados. As informações em cada elemento são apresentadas da seguinte forma:

  • Em tabela

    Tabela de resultados do Plano de Teste

  • Em árvore

    Tabela de resultados do Plano de Teste

Executando o teste

Com o elemento para visualização dos resultados adicionado e selecionado, podemos executar o plano através do menu, clicando em Executar > Iniciar e acompanhar os resultados.

Na visualização dos resultados em tabela, utilizada aqui, podemos observar alguns dados importantes que podem ser analisados:

  • Tempo da amostra: Tempo total da requisição em m/s.
  • Estado: Mostra se a requisição foi executada com sucesso ou se houve falhas.
  • Bytes: Quantidade de dados retornados pelo servidor.
  • Latency: Diferença entre o tempo que a requisição foi enviada e a hora em que a resposta foi recebida.

Para podermos analisar melhor os dados, exportamos para uma planilha eletrônica. Para exportar, basta selecionar todos os requests na tabela de visualização de resultados (um CTRL + A funciona), copiá-los com CTRL + C e colar na planilha.

Analisando os resultados

Os testes foram executados no ambiente de staging do RDStation, o qual roda em um ambiente semelhante ao de produção apenas com hardware reduzido.

Ao finalizar a execução do plano de teste, exportamos os dados de todas as requisições e agrupamos por com cache/sem cache. Observamos que remover o cache onerou em aproximadamente 25%.

Tabela de resultados da análise

Conclusão

Analisando os resultados vemos que o cache tem uma eficácia de 25% para este cenário. O que é interessante para o RDStation com uma base de clientes crescendo rapidamente.

E você, que ferramenta usa para testes de carga? Não deixe de compartilhar nos comentários :)

Jean Holderbaum

Jean Holderbaum

Full Stack Developer

Comentários