Neste artigo, compartilho minha experiência construindo uma infraestrutura de testes de carga gerida de forma eficiente com GitHub Actions e observável via integração com OpenTelemetry (OTel). O objetivo era garantir que o desempenho da nossa API pudesse ser monitorado facilmente dentro dos pipelines de CI/CD.
O Problema
Precisávamos executar testes de desempenho regularmente contra nossos ambientes de staging e produção sem intervenção manual. Além disso, as métricas geradas por esses testes precisavam ficar visíveis nos nossos dashboards centralizados do Grafana, que usam o Amazon Managed Prometheus (AMP) alimentado por um OpenTelemetry Collector.
Por que o K6?
Escolhi o K6 porque permite escrever testes em JavaScript, tornando-os acessíveis para toda a equipe. É leve, compatível com containers e tem suporte nativo para exportar métricas para OpenTelemetry.
Estrutura do caso de uso
Estruturei o repositório para lidar com diferentes tipos de testes:
- Smoke Tests: Verificações rápidas de saúde executadas em pull requests.
- Load Tests: Baselines de desempenho padrão executadas em agendamentos.
- Stress & Soak Tests: Testes mais agressivos para identificar pontos de ruptura.
Aqui está um exemplo simplificado de como estruturei um teste básico usando checks e thresholds:
import http from 'k6/http';
import { check } from 'k6';
export const options = {
thresholds: {
http_req_duration: ['p(95)<2000'], // 95% das requisições devem estar abaixo de 2s
http_req_failed: ['rate<0.01'], // Menos de 1% de falha
},
};
export default function () {
const res = http.get('https://api.staging.example.com/health');
check(res, {
'status é 200': (r) => r.status === 200,
});
}
Passo 1: Implementação no GitHub Actions
O núcleo da automação fica no GitHub Actions. Criei um workflow que permite execução agendada (cron) e acionamento manual (workflow_dispatch) para ambientes específicos.
Um desafio específico foi garantir que o binário do K6 estivesse corretamente instalado e disponível no PATH. Usar a action oficial grafana/setup-k6-action foi a solução mais confiável.
Aqui está a configuração essencial do arquivo de workflow .github/workflows/load-tests.yml:
name: K6 Load Tests
on:
schedule:
- cron: '0 0 * * 5' # Toda sexta-feira à meia-noite
workflow_dispatch:
inputs:
environment:
type: choice
options:
- staging
- production
test_type:
type: choice
options:
- smoke
- load
jobs:
run-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup k6
uses: grafana/setup-k6-action@v1
- name: Run K6 Test
run: k6 run --out opentelemetry tests/${{ inputs.test_type }}/test.js
env:
K6_OTEL_EXPORTER_TYPE: http
K6_OTEL_HTTP_EXPORTER_ENDPOINT: ${{ vars.OTEL_COLLECTOR_ENDPOINT }}
Passo 2: Integração com OpenTelemetry
Esta foi a parte mais crítica da configuração. Integrar o K6 com nosso OpenTelemetry Collector exigiu configurações específicas para garantir que as métricas viajassem do runner do GitHub Action para nosso collector e, finalmente, para o Prometheus.
O suporte nativo do K6 ao OTel é excelente, mas nuances de configuração importam.
Configuração do protocolo
Precisei definir explicitamente o tipo do exporter para http porque o collector escuta na porta 4318 para payloads HTTP/OTLP. Por padrão, algumas ferramentas assumem gRPC (porta 4317).
env:
K6_OTEL_EXPORTER_TYPE: http
K6_OTEL_HTTP_EXPORTER_ENDPOINT: ${{ vars.OTEL_COLLECTOR_ENDPOINT }}
K6_OTEL_EXPORTER_INSECURE: true
A variável de endpoint geralmente é algo como seu-domínio.com:4318. O K6 adiciona o protocolo/caminho correto se configurado apropriadamente, mas aprendi que K6_OTEL_HTTP_EXPORTER_ENDPOINT é a variável específica quando o tipo é http, enquanto K6_OTEL_EXPORTER_ENDPOINT costuma ser usada para gRPC ou defaults genéricos.
Atributos de recurso e filtragem
Em um ambiente de observabilidade compartilhado, taguear suas métricas é obrigatório. Nosso collector descarta qualquer métrica que não contenha um client_id específico. Resolvi isso injetando K6_OTEL_RESOURCE_ATTRIBUTES diretamente no pipeline:
K6_OTEL_RESOURCE_ATTRIBUTES: client_id=test3,environment=${{ matrix.environment }},service_name=k6-load-tests
Isso garante que, ao consultar k6_http_req_duration no Grafana, eu possa filtrar exatamente pela execução do teste e ambiente.
Passo 3: Simulação local com Act
Testar workflows do GitHub Actions cometendo e dando push com mensagens "fix ci" é tedioso. Integrei o act para simular o ambiente do GitHub Actions localmente.
Criando um arquivo simples de payload de evento dispatch-event.json, pude verificar o comportamento exato da injeção de variáveis de ambiente e da execução do comando K6 sem sair do terminal:
act workflow_dispatch -e .github/dispatch-event.json -W .github/workflows/load-tests.yml
Isso economizou horas de depuração, especialmente ao ajustar as variáveis de ambiente do OTel.
Conclusão
Ao combinar K6, GitHub Actions e OpenTelemetry, implementei um sistema onde o desempenho é monitorado como a saúde da aplicação.
- Automação: Não há mais execução manual dos testes de carga.
- Visibilidade: Métricas estão no mesmo dashboard que as métricas da aplicação.
-
Depuração: Testes locais com
actgarantem que o pipeline permaneça estável.
Se for montar testes de carga, recomendo priorizar o aspecto de observabilidade desde cedo. Ver gráficos em tempo real de Virtual Users (VUs) e Duração de Requisições ao lado do uso de CPU do servidor oferece insights que um relatório local isolado nunca proporciona.
Top comments (0)