
Я собираю некоторые данные локально дома на Raspberry Pi и хочу как можно быстрее отправлять их на REST API (который у меня есть) на сервере в Интернете.
Локально собранные данные могут передаваться со скоростью до 100 записей в секунду.
Если я выполню команду curl в цикле, она отправит данные... Дождусь ответа 200, а затем обработаю следующую запись... Гораздо медленнее, чем мой внутренний поток данных.
Я нашел несколько советов здесь, на Stackoverflow, и попытался адаптировать их, но они не отправляли команды curl параллельно.
Я знаю, что мой код не самый красивый (особенно в части использования функции mycurl), и я готов выслушать предложения.
#!/bin/bash
host="localhost"
port="********"
mycurl() {
data="field1=${1}&field2=${2}&field3=${3}&field4=${4}&field5=${5}&field6=${6}&field7=${7}&field8=${8}&field9=${9}&field10=${10}"
curl --output /dev/null -d $data --silent -X POST https://myapi/myendpoint;
}
export -f mycurl
#----------------------LOOP starts------------------------
while true;
do
nc -d $host $port | while IFS="," read -r f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22
do
if [ "$f15" != "" ]; then
seq 1000 | parallel --no-notice --joblog log -j0 mycurl ::: ${f5} ::: ${f7} ::: ${f8} ::: ${f15} ::: ${f16} ::: ${17} ::: ${18} ::: ${19} ::: ${20} ::: ${21};
fi
done
done
решение1
GNU Parallel имеет накладные расходы в 2-5 мс на задание, что приближается к вашим 100 записям в секунду. Чтобы уменьшить это, вы можете обернуть его в parallel --pipe
. Это должно запустить около 25000 заданий параллельно в секунду на 100-ядерной машине:
#!/bin/bash
host="localhost"
port="********"
mycurl() {
if [ "${15}" != "" ]; then
# The numbering here should probably be adjusted
data="field1=${1}&field2=${2}&field3=${3}&field4=${4}&field5=${5}&field6=${6}&field7=${7}&field8=${8}&field9=${9}&field10=${10}"
curl --output /dev/null -d $data --silent -X POST https://myapi/myendpoint;
fi
}
export -f mycurl
#----------------------LOOP starts------------------------
while true;
do
nc -d $host $port
done |
parallel -j100 --pipe --block 100k parallel --colsep , -j0 mycurl
решение2
Почему бы не перевести каждый curl
вызов в фоновый режим: curl
... &
. Помещение амперсанда в конец команды оболочки похоже на использование ;
точки с запятой, только оно переводит процесс в фоновый режим.