
Вот мой скрипт оболочки:
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 запросов на их загрузку.
Я хотел бы ускорить процесс, выполняя эти запросы параллельно.
Есть идеи?
решение1
Xargs может делать это на переднем плане, и это дает вам контроль над параллелизмом и пакетированием. Curl будет повторно использовать открытое соединение для отправки всех запросов в пакете.
-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"
, ... (иначе говоря "$@"
). Теперь мы используем 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
решение2
Вы всегда можете взглянуть нанет
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, работающих одновременно