Quieres saber cómo se comporta tu API a exactamente 500 solicitudes por segundo, no "tan rápido como N hilos puedan bombardearla". La mayoría de las herramientas de carga fijan la concurrencia y dejan que la tasa de solicitudes fluctúe. Vegeta hace lo contrario: tú estableces la tasa y envía esa cantidad de solicitudes por segundo, independientemente de cómo responda el servidor. Esa diferencia importa cuando te preocupas por el número que usa la hoja de respuestas, el rendimiento bajo una carga objetivo y la latencia que realmente prometerías en un SLO.
¿Qué es Vegeta?
Vegeta es una herramienta de prueba de carga HTTP de línea de comandos escrita en Go. También se puede usar como una biblioteca de Go, pero este tutorial se ciñe a la CLI. La idea central es una tasa de solicitudes constante. Le dices a Vegeta "envía 100 solicitudes por segundo durante 30 segundos", y mantiene ese ritmo añadiendo trabajadores según sea necesario. Si el servidor se ralentiza, Vegeta sigue emitiendo nuevas solicitudes según lo programado en lugar de esperar a que las antiguas terminen.
Ese diseño te proporciona una prueba de carga de modelo abierto. El tráfico real llega a su propio ritmo; los usuarios no pausan y esperan a tu endpoint lento antes de que aparezca el siguiente usuario. Una herramienta basada en tasas coincide con ese comportamiento.
Carga basada en tasa vs. basada en concurrencia
Aquí está la diferencia que confunde a la gente.
Una herramienta basada en concurrencia (un pool fijo de hilos o usuarios virtuales, cada uno con un bucle de solicitud-respuesta) utiliza un modelo cerrado. Cuando el servidor se ralentiza, el bucle se detiene, por lo que la tasa de solicitudes real disminuye. Pediste carga, pero la herramienta retrocedió discretamente. Eso oculta la acumulación que verías en producción.
Una herramienta basada en tasas como Vegeta utiliza un modelo abierto. Tú fijas la tasa de llegada. Si el servidor no puede seguir el ritmo, las solicitudes se ponen en cola, la latencia aumenta y el informe lo muestra. Obtienes una imagen honesta de lo que sucede cuando la demanda excede la capacidad.
Ninguno de los modelos es incorrecto. Usa la concurrencia cuando quieras saber "cuántos usuarios simultáneos puedo soportar". Usa un modelo de tasa cuando quieras saber "qué sucede a 2.000 solicitudes por segundo". Vegeta es del segundo tipo. Para un mapa más amplio del espacio de herramientas, consulta las mejores herramientas de prueba de carga de API.
Instalar Vegeta
Elige el que mejor se adapte a tu configuración.
Homebrew en macOS:
brew update && brew install vegeta
Otros gestores de paquetes:
# MacPorts
port install vegeta
# Arch Linux
pacman -S vegeta
# FreeBSD
pkg install vegeta
Desde el código fuente con Go instalado:
git clone https://github.com/tsenart/vegeta
cd vegeta
make vegeta
También puedes descargar un binario precompilado desde la página de lanzamientos de GitHub. Confirma la instalación:
vegeta --help
El pipeline central
Vegeta se construye alrededor de las tuberías de Unix. Un objetivo entra, un ataque se ejecuta y un informe sale. La ejecución útil más pequeña es una línea:
echo "GET http://localhost:8080/" | vegeta attack -duration=5s -rate=100 | vegeta report
Léelo de izquierda a derecha:
echoescribe un objetivo (un método y una URL) en la salida estándar.vegeta attacklee ese objetivo de la entrada estándar y lanza 100 solicitudes por segundo durante 5 segundos. Eso es un total de 500 solicitudes.vegeta reportlee el flujo de resultados binarios e imprime un resumen.
La bandera -rate toma solicitudes por unidad de tiempo. -rate=100 y -rate=100/1s significan lo mismo. -rate=50/500ms significa 50 solicitudes cada 500 milisegundos. Establecer -rate=0 elimina el límite y envía tan rápido como sea posible, lo cual es una prueba completamente diferente.
Un informe de texto se ve así:
Requests [total, rate, throughput] 500, 100.20, 100.18
Duration [total, attack, wait] 4.991s, 4.990s, 1.2ms
Latencies [min, mean, 50, 90, 95, 99, max] 412us, 1.3ms, 1.1ms, 1.9ms, 2.4ms, 5.1ms, 12ms
Bytes In [total, mean] 128500, 257.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:500
Error Set:
Lee primero la línea de latencia. La columna 50 es la mediana. La columna 99 es la cola: el 1 por ciento de las solicitudes fueron más lentas que eso. Las colas son donde los usuarios sienten el dolor, por lo que una media saludable con un percentil 99 feo sigue siendo un problema. Comprueba Success [ratio] y Status Codes a continuación. Un ratio de éxito del 100 por cien con todos los códigos 200 significa que el servidor soportó la carga. Cualquier código 5xx o un Error Set no vacío significa que empezó a fallar.
Guarda los resultados, luego reporta de muchas maneras
Enviar directamente a report está bien para un vistazo rápido. Para cualquier cosa que vayas a revisar, guarda primero los resultados brutos en un archivo, luego genera todos los informes que quieras a partir de ese único archivo.
echo "GET http://localhost:8080/" | \
vegeta attack -duration=10s -rate=200 -output=results.bin
Ahora la ejecución está capturada en results.bin. Genera un informe de texto:
vegeta report results.bin
Produce JSON estructurado para un panel de control o una diferencia entre ejecuciones:
vegeta report -type=json results.bin > metrics.json
Produce un histograma de latencia con los rangos que elijas:
vegeta report -type='hist[0,2ms,5ms,10ms,25ms,100ms]' results.bin
El histograma cuenta cuántas solicitudes cayeron en cada rango de latencia. Es una forma rápida de ver si la latencia está muy agrupada o dispersa en un rango amplio.
El formato del archivo de objetivos
Las API reales necesitan más que una sola solicitud GET. Mueve tus objetivos a un archivo y pásalo con -targets. El formato HTTP predeterminado está basado en líneas y es legible.
Crea targets.txt:
GET http://localhost:8080/api/users
POST http://localhost:8080/api/users
Content-Type: application/json
@./payload.json
GET http://localhost:8080/api/users/42
Algunas reglas hacen que esto funcione:
- La primera línea de cada objetivo es
MÉTODO URL. - Las líneas de encabezado siguen directamente debajo de la línea del método, una
Clave: Valorpor línea. - Una línea que comienza con
@nombra un archivo cuyo contenido se convierte en el cuerpo de la solicitud. - Una línea en blanco separa un objetivo del siguiente.
- Las líneas que comienzan con
#son comentarios.
Coloca tu cuerpo JSON en payload.json:
{ "name": "Ada", "role": "engineer" }
Ejecuta el ataque contra el archivo:
vegeta attack -targets=targets.txt -rate=50 -duration=30s | vegeta report
Vegeta cicla a través de los objetivos en orden y sigue en bucle hasta que termina la duración. También puedes añadir encabezados globales en la línea de comandos con -header, lo cual es útil para la autenticación:
vegeta attack -targets=targets.txt -rate=50 -duration=30s \
-header="Authorization: Bearer $TOKEN" | vegeta report
Para ejecuciones programáticas o de alto volumen, Vegeta también lee un formato de objetivo JSON. Cada línea es un objeto JSON, y lo seleccionas con -format=json:
{"method": "GET", "url": "http://localhost:8080/api/users"}
{"method": "POST", "url": "http://localhost:8080/api/users", "header": {"Content-Type": ["application/json"]}, "body": "eyJuYW1lIjoiQWRhIn0="}
El campo body está codificado en base64. Este formato se transmite bien, por lo que puedes generar objetivos sobre la marcha y enviarlos directamente con -lazy para la eficiencia de la memoria.
Gráficos e histogramas
Un solo número oculta tendencias. Si la latencia se degrada a mitad de una ejecución, querrás ver la curva. El comando plot de Vegeta convierte un flujo de resultados en una página HTML interactiva:
vegeta attack -targets=targets.txt -rate=100 -duration=60s | \
vegeta plot > plot.html
Abre plot.html en un navegador. Obtendrás un gráfico de series de tiempo de la latencia a lo largo de la ejecución, por lo que un aumento lento o un pico a mitad de la prueba es obvio. Puedes graficar varias ejecuciones juntas para comparar los niveles de carga:
vegeta attack -rate=50 -duration=30s -targets=targets.txt -output=50qps.bin
vegeta attack -rate=100 -duration=30s -targets=targets.txt -output=100qps.bin
vegeta plot 50qps.bin 100qps.bin > compare.html
Para entornos sin interfaz gráfica, omite el gráfico y exporta un histograma o el CSV sin procesar con encode:
vegeta encode -to=csv results.bin > results.csv
Cuándo usar Vegeta
Usa Vegeta cuando la pregunta sea sobre tasa y capacidad:
- Necesitas rendimiento y latencia a una tasa específica de solicitudes por segundo.
- Quieres encontrar la tasa a la que la latencia o la tasa de error comienzan a aumentar.
- Estás comparando dos versiones o dos configuraciones de infraestructura bajo una carga idéntica y repetible.
- Quieres una herramienta programable que se integre en un pipeline de shell y un trabajo de CI sin interfaz gráfica.
Es un instrumento enfocado. Envía solicitudes HTTP a una tasa y mide cómo responde el servidor. No scripta recorridos de usuario de varios pasos con lógica de bifurcación, y no valida los cuerpos de las respuestas más allá de los códigos de estado. Ese enfoque es una característica; mantiene la herramienta pequeña y los resultados limpios.
Si lo estás comparando con otras herramientas, las comparaciones en pruebas de carga con k6 y pruebas de carga con JMeter cubren las alternativas de modelo de concurrencia. Para los conceptos y métricas subyacentes, el tutorial de pruebas de rendimiento de API es una buena introducción.
Dónde encaja el testing funcional
Las pruebas de carga responden "¿es lo suficientemente rápido?". No responden "¿es correcto?". Una ejecución de Vegeta puede informar el 100 por ciento de códigos 200 mientras que el endpoint devuelve el usuario incorrecto, un precio obsoleto o un campo JSON mal formado. Cada una de esas respuestas es un 200 rápido y exitoso en lo que a una herramienta de carga respecta.
La corrección necesita una verificación diferente: aserciones sobre el cuerpo de la respuesta, el esquema y las reglas de negocio. Eso es pruebas funcionales, y debe realizarse antes y junto a tus ejecuciones de carga. El patrón saludable es validar que la API es correcta, luego medir cómo se comporta bajo una cierta tasa.
Aquí es donde Apidog complementa una herramienta como Vegeta en lugar de competir con ella. En Apidog construyes escenarios de prueba con aserciones visuales sobre el estado, los encabezados y los campos JSON, encadenas solicitudes y las diriges desde archivos de datos. Confirmas que la API devuelve los datos correctos. Vegeta luego confirma que se mantiene rápida cuando ese camino correcto es accedido cientos de veces por segundo. Dos herramientas, dos preguntas.
Apidog también incluye una CLI sin interfaz gráfica para que esos escenarios funcionales se ejecuten en el mismo pipeline de CI que tu paso de carga. Instálalo con Node:
npm install -g apidog-cli
Luego ejecuta un escenario o suite guardado por ID, con reporteros para tu pipeline:
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
La bandera -t toma el ID del escenario, carpeta o suite, -e toma el ID del entorno, y -r selecciona uno o más reporteros (cli, html, json, junit). La salida junit se integra en la mayoría de los paneles de CI. Consulta el tutorial de línea de comandos de Apidog CLI para una ejecución paso a paso, y la guía de pipeline de CI/CD para un flujo de trabajo de copiar y pegar. Ejecuta primero la puerta funcional, luego deja que Vegeta mida los endpoints que pasaron.
Preguntas frecuentes
¿Vegeta soporta solicitudes POST con cuerpo?
Sí. En el archivo de objetivos HTTP, coloca el método y la URL en la primera línea, añade un encabezado Content-Type, y haz referencia a un archivo de cuerpo con @./payload.json. En el formato JSON, establece los campos method, url y un campo body codificado en base64.
¿Qué hace -rate=0?
Elimina el límite de tasa y envía solicitudes tan rápido como lo permitan los trabajadores y las conexiones. Esa es una prueba de rendimiento máximo, que es diferente de una prueba controlada de tasa constante. Para mediciones de capacidad repetibles, establece una tasa explícita.
¿Cómo leo los percentiles de latencia?
La línea de latencia del informe muestra el mínimo, la media y los percentiles 50, 90, 95, 99 y máximo. Concéntrate en los percentiles 95 y 99. Describen la cola lenta que experimentan los usuarios reales, la cual una media por sí sola puede ocultar.
¿Puede Vegeta verificar que mi API devuelve datos correctos?
No. Mide el rendimiento, la latencia y los códigos de estado. No realiza aserciones sobre los cuerpos de las respuestas o los esquemas. Combínalo con una herramienta de pruebas funcionales para la corrección, luego usa Vegeta para la tasa y la latencia.
¿Cómo ejecuto Vegeta en CI?
Es un único binario que lee la entrada estándar y escribe los resultados, por lo que se integra en cualquier paso de shell. Guarda los resultados con -output, luego genera un informe de texto o JSON como un artefacto de construcción. Añade una puerta funcional, como la CLI de Apidog, antes del paso de carga para que solo midas los endpoints que ya pasaron sus aserciones.
