Testes de carga
Como descobrir o limite do sistema antes que os usuários descubram.
As decisões de um teste de carga são cinco: qual ferramenta, qual modelo de carga, qual cenário, onde rodar e como ler o resultado.
Qual ferramenta
| Ferramenta | Scripts em | Pontos fortes |
|---|---|---|
| k6 | JavaScript | Modelos aberto e fechado, limites que reprovam o teste, saída para Prometheus e Grafana |
| Gatling | Scala, Java, Kotlin, JavaScript | Relatórios detalhados, modelo aberto por padrão |
| Locust | Python | Cenários com lógica complexa, interface web |
| JMeter | Interface gráfica e XML | Muitos protocolos; mais pesado de manter |
| wrk2, vegeta, oha | Linha de comando | Taxa constante para um endereço, rápidos para medir um ponto |
| Serviços gerenciados (Grafana Cloud k6, Azure Load Testing, Gatling Enterprise) | Os mesmos scripts | Gerar carga de várias regiões, sem montar a infraestrutura |
Para a maioria dos times, o k6 é um bom começo: o script é código, fica no repositório e roda na integração contínua. O que mais importa é usar uma ferramenta que suporte o modelo aberto.
Qual modelo de carga
| Modelo | Quando usar | Executor no k6 |
|---|---|---|
| Aberto (taxa de chegada) | Tráfego de usuários da internet, APIs públicas | constant-arrival-rate, ramping-arrival-rate |
| Fechado (usuários fixos) | Um número fixo de clientes: trabalhadores, integrações com concorrência limitada | constant-vus, ramping-vus |
No teste do nível Conceito, contra um servidor com pausas de 1 segundo, o modelo fechado relatou p95 de 8 ms, e o aberto, 848 ms. Para tráfego de usuários, use o modelo aberto, ou, no mínimo, meça a latência a partir do instante em que o pedido deveria ter saído.
Qual cenário
| Decisão | Recomendação |
|---|---|
| Rotas | A mistura real de tráfego, tirada dos logs ou das métricas: 70% leitura de produto, 20% busca, 10% compra, por exemplo |
| Dados | Volume e distribuição de produção: muitos produtos, usuários diferentes, alguns muito populares |
| Autenticação | Usuários de teste diferentes; um só usuário concentra tudo num registro e esconde a disputa |
| Aquecimento | Descartar o primeiro minuto: caches frios, compilação da JVM e do .NET, pools vazios |
| Duração | Minutos para carga e estresse; horas para resistência |
| Degraus | Subir em degraus até passar do joelho; um ponto só não mostra a curva |
Onde rodar
| Ambiente | Vantagens | Cuidados |
|---|---|---|
| Uma cópia de produção | O resultado vale para produção | Custo; manter a cópia parecida |
| Ambiente de testes menor | Barato; serve para comparar versões | O limite absoluto não vale; a tendência sim |
| Produção, fora do horário de pico | O ambiente real | Risco; tráfego de teste identificado; dados de teste isolados |
E o gerador fora do alvo: na mesma máquina, os dois disputam CPU, e o gerador vira o gargalo. Nos testes deste tópico, o servidor ficou preso a um núcleo e o gerador, a outros quatro. Confira também se o próprio gerador não é o limite: CPU do gerador a 100% invalida o teste.
Como ler o resultado
| Sinal | Significado |
|---|---|
| Respostas por segundo param de crescer, a latência dispara | Passou do joelho; a capacidade é a vazão onde isso começa (247/s no teste) |
| p50 estável, p99 subindo | Fila começando, pausas, ou disputa por um recurso |
| Erros por tempo esgotado | A fila ficou maior que o tempo limite |
| Latência subindo devagar ao longo de horas | Vazamento: memória, conexões, arquivos abertos |
| CPU baixa no servidor e latência alta | Espera: banco, travas, pool de conexões, serviço externo |
Durante o teste, observe o servidor ao mesmo tempo: CPU, memória, conexões do banco, tamanho das filas. O gerador diz que o sistema ficou lento; as métricas do servidor e um perfil, como mostra o tópico de profiling, dizem por quê.
Limites que reprovam o teste
Transforme os objetivos em limites automáticos e rode o teste na integração contínua para as rotas críticas:
export const options = {
thresholds: {
http_req_duration: ["p(95)<200", "p(99)<500"], // em ms
http_req_failed: ["rate<0.01"], // menos de 1% de erros
},
};Assim, uma mudança que degrada o desempenho falha antes de ir para produção.
Resumo da decisão
- Uma ferramenta com modelo aberto, com o script no repositório.
- Taxa de chegada para simular usuários; medir sempre a partir do instante planejado.
- Percentis (p95, p99) e erros, nunca só a média.
- Degraus até passar do joelho, para conhecer a capacidade e o modo de falha.
- Dados e mistura de rotas realistas, com aquecimento e o gerador em outra máquina.
- Limites automáticos na integração contínua para as rotas críticas.
O próximo nível mostra um gerador de modelo aberto nas cinco linguagens e os scripts do k6 usados nos testes.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Planejar o teste de carga do meu sistema
Quero testar quanto o meu sistema aguenta antes de um evento de pico. Pergunte qual é o sistema, o tráfego esperado no pico, as rotas mais usadas, onde ele roda e se há um ambiente parecido com produção. Monte comigo o plano: a ferramenta, o modelo de carga, a mistura de rotas, os dados de teste, os degraus, a duração, o que observar no servidor durante o teste e os critérios de aprovação.
Escolher a ferramenta de teste de carga
Estou escolhendo uma ferramenta de teste de carga. Pergunte qual linguagem o time conhece, que protocolos preciso testar, se o teste vai rodar na integração contínua e se preciso gerar carga de várias regiões. Compare para o meu caso k6, Gatling, Locust, JMeter e uma ferramenta simples como vegeta ou oha, inclusive quanto ao suporte ao modelo aberto. Recomende uma.
Testes de carga na integração contínua
Quero rodar testes de carga automaticamente para pegar regressões de desempenho. Pergunte qual serviço de integração contínua e ferramenta eu uso, e quais rotas são críticas. Me ajude a montar: um teste curto com limites que reprovam o pipeline, o ambiente onde ele roda, como lidar com a variação entre execuções, onde guardar o histórico dos resultados e quando rodar o teste completo.