Testes de performance: introduzindo carga com k6 ou JMeter
1. Fundamentos dos Testes de Performance
Testes de performance são essenciais para garantir que sistemas web e APIs suportem a carga esperada em produção. Três tipos principais se destacam:
- Testes de carga: simulam o uso normal do sistema para verificar comportamento sob tráfego esperado.
- Testes de estresse: aumentam progressivamente a carga até o ponto de falha, identificando limites do sistema.
- Testes de resistência: mantêm carga constante por longos períodos para detectar vazamentos de memória ou degradação gradual.
As métricas fundamentais incluem:
- Latência: tempo de resposta de uma requisição, medida em milissegundos.
- Throughput: número de requisições processadas por segundo.
- Taxa de erro: percentual de requisições que retornam códigos de erro (4xx, 5xx).
- Percentis (p50, p95, p99): distribuição de latência — p99 indica que 99% das requisições são mais rápidas que aquele valor.
Realizar testes antes de ir para produção evita surpresas como lentidão generalizada, timeouts e perda de receita durante picos de acesso.
2. JMeter: A Ferramenta Clássica e Robusta
JMeter é uma ferramenta madura baseada em Java, amplamente adotada por sua interface gráfica e vasto ecossistema de plugins.
Arquitetura básica
Um plano de teste no JMeter contém:
- Thread Group: define número de usuários virtuais, ramp-up e duração.
- Samplers: realizam requisições HTTP, JDBC, SOAP, etc.
- Listeners: exibem resultados em tabelas, gráficos e relatórios.
Exemplo prático: script de carga simples
Crie um plano de teste com as seguintes configurações:
Thread Group:
- Número de threads (usuários): 50
- Período de ramp-up (segundos): 10
- Contagem de loops: 10
HTTP Request Defaults:
- Protocolo: https
- Servidor: api.exemplo.com
- Porta: 443
HTTP Request:
- Método: GET
- Path: /v1/produtos
Listener: Summary Report
- Salvar resultados em arquivo CSV
Execute em modo headless para produção:
jmeter -n -t script.jmx -l resultados.csv -e -o relatorio/
Vantagens e limitações
Vantagens: interface gráfica intuitiva, suporte a múltiplos protocolos (HTTP, JDBC, FTP, JMS), relatórios integrados.
Limitações: consumo elevado de memória para grandes cargas, scripts em XML (difícil versionamento), curva de aprendizado para cenários complexos.
3. k6: Modernidade e Código como Script
k6 é uma ferramenta open-source escrita em Go, com scripts em JavaScript, projetada para integração contínua e pipelines DevOps.
Conceitos fundamentais
- VUs (Virtual Users): cada VU executa o script de forma independente.
- Stages: definem como a carga varia ao longo do tempo (ramp-up, steady, ramp-down).
- Checks: validações de resposta (status code, tempo máximo).
Exemplo prático: teste de carga com k6
Crie um arquivo teste-carga.js:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 20 }, // ramp-up para 20 VUs
{ duration: '1m', target: 20 }, // carga constante
{ duration: '30s', target: 0 }, // ramp-down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% das requisições < 500ms
http_req_failed: ['rate<0.05'], // taxa de erro < 5%
},
};
export default function () {
const res = http.get('https://api.exemplo.com/v1/produtos');
check(res, {
'status code é 200': (r) => r.status === 200,
'tempo de resposta < 300ms': (r) => r.timings.duration < 300,
});
sleep(1); // pausa de 1 segundo entre requisições
}
Execute localmente:
k6 run teste-carga.js
Para gerar relatório HTML:
k6 run teste-carga.js --out json=resultados.json
k6 convert resultados.json --out html > relatorio.html
Integração CI/CD
k6 pode ser executado em pipelines GitHub Actions, GitLab CI ou Jenkins sem interface gráfica:
# Exemplo de comando em pipeline
k6 run --vus 50 --duration 60s teste-carga.js
4. Comparação Prática: JMeter vs. k6
| Aspecto | JMeter | k6 |
|---|---|---|
| Curva de aprendizado | Moderada (interface gráfica) | Baixa (JavaScript) |
| Consumo de recursos | Alto (Java VM) | Baixo (Go runtime) |
| Execução distribuída | Nativa (Master-Slave) | k6 Cloud ou Kubernetes |
| Versionamento de scripts | Difícil (XML) | Fácil (JS em Git) |
| Protocolos suportados | HTTP, JDBC, JMS, FTP, SOAP | HTTP/1.1, HTTP/2, gRPC, WebSocket |
| Relatórios visuais | Integrados (Listener) | k6 Cloud ou grafana/k6 |
Quando usar JMeter: equipes com forte tradição em QA, necessidade de protocolos legados (JDBC, JMS), cenários com interface gráfica para stakeholders não-técnicos.
Quando usar k6: pipelines DevOps, times de desenvolvimento que preferem código, testes de APIs REST e gRPC, ambientes com recursos limitados.
Usar ambas: JMeter para testes de aceitação manuais e k6 para testes automatizados em CI/CD.
5. Planejando um Cenário de Carga Realista
Definindo objetivos
- Pico esperado: 1000 requisições/segundo durante 10 minutos.
- SLA: p95 < 500ms, taxa de erro < 1%.
- Limites aceitáveis: degradação gradual, sem falhas catastróficas.
Modelagem de usuários
Stages recomendados:
1. Ramp-up: 0 → 100 VUs em 2 minutos
2. Steady: 100 VUs por 5 minutos
3. Ramp-down: 100 → 0 VUs em 2 minutos
Dados de teste
Evite efeitos de cache utilizando:
- Parametrização: dados diferentes para cada VU (tokens, IDs de usuário).
- Headers aleatórios: User-Agent, Accept-Language.
- Dados realistas: use datasets com CSV ou JSON.
Exemplo com k6:
import { SharedArray } from 'k6/data';
const dados = new SharedArray('usuarios', function () {
return JSON.parse(open('./usuarios.json'));
});
export default function () {
const usuario = dados[Math.floor(Math.random() * dados.length)];
// usa usuario.token e usuario.id na requisição
}
6. Analisando Resultados e Identificando Gargalos
Leitura de relatórios
Com k6, analise o resumo final:
✓ status code é 200
✓ tempo de resposta < 300ms
http_req_duration........: avg=245ms min=120ms med=230ms max=890ms
http_req_duration........: p(90)=380ms p(95)=450ms p(99)=720ms
http_req_failed..........: 2.3% ✓ 23 ✗ 977
http_reqs................: 1000 16.67/s
Sinais de alerta:
- p99 muito acima de p95: picos de latência indicam contenção de recursos.
- Taxa de erro crescente durante steady state: degradação sob carga.
- Throughput constante mesmo aumentando VUs: limite do sistema.
Correlação com infraestrutura
Combine métricas de performance com:
- APM (Application Performance Monitoring): New Relic, Datadog.
- Logs do servidor: Nginx, aplicação (ELK Stack).
- Métricas de infra: CPU, memória, I/O de disco e rede.
Estratégias de otimização:
- Código: otimizar consultas N+1, usar cache local.
- Banco de dados: índices faltantes, queries lentas.
- Cache: Redis, CDN para conteúdo estático.
- Escalabilidade: horizontal (mais instâncias) ou vertical (mais recursos).
7. Boas Práticas e Armadilhas Comuns
Armadilhas a evitar
- Testar em produção sem isolamento: pode degradar experiência de usuários reais.
- Ignorar warm-up: sistemas com cache a frio apresentam latência maior no início.
- Dados estáticos: todos os VUs acessando o mesmo recurso geram resultados irreais.
Boas práticas
- Versionamento de scripts: mantenha scripts em Git com o código da aplicação.
- Repetibilidade: use sementes fixas para dados aleatórios.
- Ambiente isolado: réplica de produção com dados anonimizados.
- Monitoramento contínuo: execute testes a cada deploy.
Quando usar cada ferramenta
| Cenário | Ferramenta recomendada |
|---|---|
| Teste rápido de API REST | k6 |
| Teste de banco de dados (JDBC) | JMeter |
| Pipeline CI/CD | k6 |
| Relatório visual para stakeholders | JMeter |
| Teste de WebSocket em tempo real | k6 |
| Protocolo legado (FTP, JMS) | JMeter |
Referências
- Documentação oficial do k6 — Guia completo de instalação, scripts, métricas e integração CI/CD.
- Apache JMeter User Manual — Documentação oficial com exemplos de planos de teste, listeners e configurações.
- k6 vs JMeter: Which Load Testing Tool Should You Choose? — Artigo da Grafana comparando desempenho, custo e casos de uso de ambas as ferramentas.
- JMeter Distributed Testing Step-by-Step — Tutorial prático sobre execução distribuída de testes de carga com JMeter.
- k6: Load Testing for Engineers — Playlist oficial do k6 no YouTube com tutoriais para iniciantes e avançados.
- Best Practices for Performance Testing with JMeter — Guia de boas práticas para criar scripts de performance robustos no JMeter.
- k6 Cloud: Distributed Load Testing — Plataforma gerenciada para executar testes de carga em escala global com k6.