Varias formas de hacer pruebas de stress a una url

Una vez que hemos programado algo, una web, un api o cualquier otra cosa que van a utilizar muchas personas a la vez nos entra la necesidad inmediata de, después de las pruebas unitarias, poder pasarle unas pruebas de stress para ver cuanta gente puede entrar a la vez antes de que el sistema reviente o, en el peor de los casos, ver si hay algún problema de programación que nos impide tener peticiones concurrentes con seguridad.

Servidor bajo asedio... Imagen generada por AI

Solo os voy a presentar los más sencillos, aunque luego hay herramientas mucho más completas que ya se deben usar en el momento de QA para comprobar si los requisitos del sistema se cumplen (máximo número de peticiones por minuto / curva de carga / evolución del tiempo de respuesta, etc.).. Pero vamos, que ahora mismo solo queremos ver si se puede llamar a nuestro api o web concurrentemente…

siege

Este es el comando más sencillo que he encontrado, pero a la vez es muy eficiente en lo que se puede hacer con él.

siege -c10 -r1 https://blaba.com

Tras un tiempo de ejecución (depende de los parámetros c: concurrencia y r: repeticiones) se recibirá una salida como esta:

{ "transactions": 140,
"availability": 100.00,
"elapsed_time": 3.12,
"data_transferred": 3.48,
"response_time": 0.22,
"transaction_rate": 44.87,
"throughput": 1.11,
"concurrency": 9.68,
"successful_transactions": 140,
"failed_transactions": 0,
"longest_transaction": 0.33,
"shortest_transaction": 0.04
}

Ahí ya podemos ver cual es el ratio de fallo para esa concurrencia y los tiempos máximos y mínimos para cada transacción. Guay…

Ahora bien, el problema viene de que solo podemos hacer peticiones GET (podemos poner las cabeceras que queramos, pero no hay manera de hacer una petición POST, por ejemplo). Así pues si tenemos que probar un API que tiene algo más que peticiones GET tendremos que usar otra cosa…

Sigue habiendo una infinidad de herramientas muy buenas para hacer estas cosas, como Jmeter y otras, pero para unas pruebas de carga básicas vamos a continuar con el camino «barato»

curl + bash

Si estamos en linux, tenemos suerte (el siege también es de linux, pero seguro que hay un port para tu sistema operativo). Apuntad esto:

Primero hay que instalar paralell que no está en la distribución por defecto:

sudo apt install parallel

Luego podremos escribir algo como esto:

seq 100 | parallel --max-args 0 --jobs 10 "./curl_to.sh"

Y en curl_to.sh poned el comando curl con el que vais a probar, por ejemplo este:

curl --location 'https://blabla.com/api/v1/micomando' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIU...CvuTuF30k8XEFg_XL-gJyK-8rT4htC7HTHxbtDSGN8' --data '{ "userid": "418043893","message": "Hola payo…..", "uuid": "kk"}'

Este comando de antes lo que hace, básicamente, es lanzar una petición POST con un cuerpo JSON y una cabecera de autenticación (con un token JWT por ejemplo). Este código lo podemos sacar de postman, por ejemplo diciendole que queremos generar código para curl.

Si lanzamos el comando seq, lo que hace es generar una secuencia de números (en este caso de 1 a 100, y paralell lo que hace es lanzarnos de manera paralela (10 cada vez) el comando que hemos especificado… Con esto conseguiremos lanzar 100 veces 10 peticiones paralelas.

Obviamente no es perfecto, pero habremos podido simular una carga paralela sin tener que instalar nada en nuestro ordenador. Si eso lo combinamos con el comando time (os lo dejo como ejercicio) también podríamos sacar estadísticas de las ejecuciones.

En próximas entradas veremos como usar algunas herramientas muy potentes para pruebas de carga, pero por ahora, ya podéis empezar a estresar a vuestro servidor.

Deja una respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.