我有以下 shell 脚本。问题是我想并行/并发运行事务,而无需等待一个请求完成即可转到下一个请求。例如,如果我发出 20 个请求,我希望它们同时执行。
for ((request=1;request<=20;request++))
do
for ((x=1;x<=20;x++))
do
time curl -X POST --header "http://localhost:5000/example"
done
done
有什么指南吗?
您可以使用
xargs
和 -P
选项来并行运行任何命令:
seq 1 200 | xargs -n1 -P10 curl "http://localhost:5000/example"
这将运行
curl
命令 200 次,最多并行 10 个作业。
使用
xargs -P
选项,您可以并行运行任何命令:
xargs -I % -P 8 curl -X POST --header "http://localhost:5000/example" \
< <(printf '%s\n' {1..400})
这将运行给定的
curl
命令 400
次,一次并行运行最多 8
作业。
2020 年更新:
Curl 现在可以并行获取多个网站:
curl --parallel --parallel-immediate --parallel-max 3 --config websites.txt
websites.txt 文件:
url = "website1.com"
url = "website2.com"
url = "website3.com"
这是对
@saeed's
答案的补充。
我遇到了一个问题,它向以下主机发出了不必要的请求
0.0.0.1, 0.0.0.2 .... 0.0.0.N
原因是命令
xargs
将参数传递给curl命令。为了防止传递参数,我们可以使用 -I
标志来指定用哪个字符来替换参数。
所以我们将使用它,
... xargs -I '$' command ...
现在,只要找到
xargs
文字,$
就会替换参数。如果没有找到,则参数不会通过。所以使用这个最终命令将是。
seq 1 200 | xargs -I $ -n1 -P10 curl "http://localhost:5000/example"
注意:如果您在命令中使用
$
,请尝试将其替换为其他未使用的字符。
除了
@saeed's
答案之外,我创建了一个通用函数,它利用函数参数在并行的N
作业中总共触发命令M
次
function conc(){
cmd=("${@:3}")
seq 1 "$1" | xargs -n1 -P"$2" "${cmd[@]}"
}
$ conc N M cmd
$ conc 10 2 curl --location --request GET 'http://google.com/'
这将以两个最大并行度触发
10
curl 命令。
将此功能添加到
bash_profile.rc
中会更容易。 要点
最后添加“等待”,并将其背景化。
for ((request=1;request<=20;request++))
do
for ((x=1;x<=20;x++))
do
time curl -X POST --header "http://localhost:5000/example" &
done
done
wait
它们都会输出到同一个标准输出,但您可以将时间结果(以及标准输出和标准错误)重定向到命名文件:
time curl -X POST --header "http://localhost:5000/example" > output.${x}.${request}.out 2>1 &
想分享我如何将并行 xargs 与 curl 结合使用的示例。
使用 xargs 的优点是您可以指定将使用多少个线程来并行卷曲,而不是使用带“&”的卷曲,这将同时安排所有卷曲,比如说 10000 个卷曲。
希望对smdy有帮助:
#!/bin/sh
url=/any-url
currentDate=$(date +%Y-%m-%d)
payload='{"field1":"value1", "field2":{},"timestamp":"'$currentDate'"}'
threadCount=10
cat $1 | \
xargs -P $threadCount -I {} curl -sw 'url= %{url_effective}, http_status_code = %{http_code},time_total = %{time_total} seconds \n' -H "Content-Type: application/json" -H "Accept: application/json" -X POST $url --max-time 60 -d $payload
.csv 文件每行有 1 个值,将插入到 json 负载中
根据 @isorylcyanide 提供的解决方案和 @Dario Seidl 的评论,我发现这是最好的响应,因为它同时处理curl和httpie。
# conc N M cmd - fire (N) commands at a max parallelism of (M) each
function conc(){
cmd=("${@:3}")
seq 1 "$1" | xargs -I'$XARGI' -P"$2" "${cmd[@]}"
}
例如:
conc 10 3 curl -L -X POST https://httpbin.org/post -H 'Authorization: Basic dXNlcjpwYXNz' -H 'Content-Type: application/json' -d '{"url":"http://google.com/","foo":"bar"}'
conc 10 3 http --ignore-stdin -F -a user:pass httpbin.org/post url=http://google.com/ foo=bar
要使用 cURL 发送多个请求,您只需使用此行
for i in $(seq 100); do $(curl 'http://192.168.0.1/' > /dev/null 2>&1 &) ; done ;
即可并行化您指定的连接数。