С Башем

С Башем

Вот мой скрипт оболочки:

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, работающих одновременно

Связанный контент