
Este es mi script de shell:
for i in `seq 1 $1`; do
filename=randomfile$(uuidgen).txt
head -c $2 </dev/urandom > $filename
checksum256=$(sha256sum $filename | awk '{ print $1 }')
attrs=$(jq -n --arg cf "$checksum256" '{ "confidential":"N", "transactionId": "sdf", "codiDirCorp": "CorpCode", "expiration": "10/10/2025", "description": "desc", "locked": "N", "title": "titol", "docHash": $cf }')
curl -X POST \
'http://localhost:8083/documents?application=RDOCUI&user=nif' \
-F docFile=@$filename \
-F 'docAttributes='"${attrs}"''
done
Como puedes ver, estoy generando varios archivos con contenido aleatorio.
Después de eso, simplemente realizo una solicitud curl para poder cargarlos.
Para ejecutar ese comando, simplemente escribo:
$ ./stress.sh 1000 200K
Aquí genero 1000 archivos y 1000 solicitudes para cargarlos.
Me gustaría acelerar la ejecución de esas solicitudes en paralelo.
¿Algunas ideas?
Respuesta1
Xargs puede hacer eso en primer plano y le brinda control sobre el paralelismo y el procesamiento por lotes. Curl reutilizará una conexión abierta para enviar todas las solicitudes en un lote.
-P 42
define cuántos curl
s ejecutar a la vez.
-n 23
define cuántas solicitudes curl
manejará cada invocación.
-n 1
desactiva el procesamiento por lotes.
con golpe
#! /bin/bash
URL='http://localhost:8083/documents?application=RDOCUI&user=nif'
for i in `seq $1`
do
filename=randomfile$(uuidgen).txt
head -c $2 </dev/urandom > $filename
export checksum256=$(sha256sum $filename | awk '{ print $1 }')
attrs=$(jq -n '{ "foo": "bar", "docHash": env.checksum256 }')
printf -- '--next %q -F docFile=@%q -F docAttributes=%q\0' "$URL" "$filename" "$attrs"
done |
xargs -0 -n 23 -P 42 bash -c 'eval "$0" "$@"' curl
El for
bucle escribe \0
grupos separados de argumentos separados por espacios en la tubería para que Xargs los lea. Esos argumentos quieren pasarse a Curl. Xargs, a su vez, se los pasa a Bash, por lo que se asignan a "$1"
, "$2"
, ... (también conocido como "$@"
). Ahora usamos eval
para desagrupar los argumentos. Todos los caracteres especiales se han escapado correctamente usando printf %q
, por lo que Bash no eliminará comillas ni dividirá palabras no deseadas.
"$0" "$@"
se expandirá acurl --next http://l... --next ...
Curl intentará realizar solo un protocolo de enlace TCP y reutilizar esa conexión persistente para enviar todas las solicitudes enumeradas en sus argumentos. Dependiendo del tamaño de la solicitud, esto puede generar una aceleración notable.
Con guión
Dash no es compatible printf %q
, pero si tu formato JSON puede sacrificarse (a través de jq -c
), puedes escaparlo con printf '%s'
. También tendremos que confiar en el supuesto de que ni JSON ni otros argumentos contienen '
.
#! /bin/sh
# ...
attrs=$(jq -n -c '{ "foo": "bar", "docHash": env.checksum256 }')
printf -- "--next %s -F 'docFile=@%s' -F 'docAttributes=%s'\0" "$URL" "$filename" "$attrs"
done |
xargs -0 -n 23 -P 42 sh -c 'eval "$0" "$@"' curl
Sinfor
Usted preguntó específicamente acerca de ejecutar en paralelo la parte de la solicitud. Pero si desea ejecutar en paralelo todo el script, puede escribir el comando de la siguiente manera
$ seq 1000 | xargs -n 1 -P 42 ./stress.sh 1 200K
Respuesta2
Siempre puedes echar un vistazo anohup
for i in `seq 1 $1`; do
filename=randomfile$(uuidgen).txt
head -c $2 </dev/urandom > $filename
checksum256=$(sha256sum $filename | awk '{ print $1 }')
attrs=$(jq -n --arg cf "$checksum256" '{ "confidential":"N", "transactionId": "sdf", "codiDirCorp": "CorpCode", "expiration": "10/10/2025", "description": "desc", "locked": "N", "title": "titol", "docHash": $cf }')
nohup curl -X POST \
'http://localhost:8083/documents?application=RDOCUI&user=nif' \
-F docFile=@$filename \
-F 'docAttributes='"${attrs}"''
done
nohup le dice al shell que ejecute el proceso en segundo plano sin la intervención del usuario, ignorando las señales de colgar. Por lo tanto, deberías tener varios CURL ejecutándose al mismo tiempo.