Это мой сценарий оболочки:
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
Как видите, я генерирую несколько файлов со случайным содержанием.
После этого я просто выполняю curl-запрос, чтобы загрузить их.
Чтобы выполнить эту команду, я просто набираю:
$ ./stress.sh 1000 200K
Здесь я генерирую 1000 файлов и 1000 запросов на их загрузку.
Я хотел бы ускорить выполнение этих запросов параллельно.
Любые идеи?
Xargs может делать это на переднем плане и дает вам контроль над параллелизмом и пакетной обработкой.
-P 42
определяет, сколько curl
бежать за раз.
-n 23
определяет, сколько запросов каждый curl
вызов будет обрабатывать. -n 1
отключает пакетирование.
#! /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
В for
цикл пишет \0
-разделенные пробелами группы аргументов в канал для чтения Xargs. Эти аргументы нужно передать в Curl. Xargs, в свою очередь, передает их Bash, поэтому они назначаются "$1"
, "$2"
, ... (a.k.a. "$@"
). Теперь мы используем eval
разгруппировать аргументы. Все специальные символы были правильно экранированы с помощью printf %q
, поэтому Bash не будет удалять ненужные кавычки или разбивать слова. "$0" "$@"
расширится до curl --next http://l... --next ...
Curl попытается выполнить только одно рукопожатие TCP и повторно использовать это постоянное соединение для отправки всех запросов, перечисленных в его аргументах. В зависимости от размера запроса, это может дать заметное ускорение.
Dash не поддерживает printf %q
, но если вашим форматированием JSON можно пожертвовать (через jq -c
) вы можете избежать этого с помощью printf '%s'
. Нам также придется полагаться на предположение, что ни JSON, ни другие аргументы не содержат '
.
#! /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
for
Вы спросили конкретно о параллельном запуске части запроса. Но если вы хотите запустить весь скрипт параллельно, вы можете ввести команду следующим образом
$ seq 1000 | xargs -n 1 -P 42 ./stress.sh 1 200K
Вы всегда можете взглянуть на нету
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 указывает оболочке запускать процесс в фоновом режиме без ввода данных пользователем, игнорируя сигналы зависания. Таким образом, у вас должно быть одновременно запущено несколько CURL