【问题标题】:Run multiple curl commands in parallel并行运行多个 curl 命令
【发布时间】:2018-03-03 21:20:56
【问题描述】:

我有以下 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

有什么指南吗?

【问题讨论】:

  • curl -X POST ... &amp;?

标签: bash shell curl


【解决方案1】:

在末尾添加“等待”,并将它们作为背景。

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 &

【讨论】:

  • 我试过这个,但它给了我其他问题。不过这很有帮助。让我们也将时间重定向到文件。
  • “输出到文件”问题很棘手,可能必须发送到同步缓冲区(通过 GNU 并行)、命名管道或群。
【解决方案2】:

使用xargs -P 选项,您可以并行运行任何命令:

xargs -I % -P 8 curl -X POST --header "http://localhost:5000/example" \
< <(printf '%s\n' {1..400})

这将运行给 curl 命令 400 次,最多并行 8 个作业。

【讨论】:

  • -P 并行运行给定数量的进程。 printf '%s\n' {1..400} 将打印从 1 到 400 的数字,curl 将运行总共 400 次,最多并行 8 个作业。
  • 是否可以在新行中打印每个输出?
  • 看到这个答案:stackoverflow.com/a/61249019/548225 你可以在xargs 中运行一个 bash 脚本,并且可以在那里做任何事情
【解决方案3】:

您可以使用xargs-P 选项并行运行任何命令:

seq 1 200 | xargs -n1 -P10  curl "http://localhost:5000/example"

这将运行 curl 命令 200 次,最多并行 10 个作业。

【讨论】:

  • 对我来说它也连接到 0.0.0.1、0.0.0.2 等等
  • 这对我有用,但由于某种原因,它在完成后不会退出命令,并保持所有连接打开(使用netstat -an | wc -l 查看打开的连接)它这样做的任何原因?有没有办法让它在最后退出?
  • 是的,它会在 curl 命令的末尾附加数字。简单的解决方法是 seq 1 200 | xargs -Iname -P10 curl "http://localhost:5000/example" 使用 I 参数我们为参数指定占位符,然后我们在命令调用中省略参数
【解决方案4】:

添加到@saeed's 答案,我创建了一个通用函数,该函数利用函数参数在M 并行作业中触发总共N 次命令

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 使其更容易。 Gist

【讨论】:

  • 谢谢,很方便。注意: xargs 将从seq 读取的索引传递给命令。例如。 conc 2 2 echo test 将打印 test 1\ntest 2。为避免这种情况,使用 -I'$XARGI' 而不是 -n1 有效(如果需要索引,您可以在命令中使用 $XARGI,如果不需要,则将其省略)。
【解决方案5】:

这是对@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"

注意:如果您在命令中使用$,请尝试将其替换为其他未使用的字符。

【讨论】:

    【解决方案6】:

    想分享我的示例,我如何将并行 xargs 与 curl 结合使用。

    使用 xargs 的优点在于,您可以指定将使用多少线程来并行化 curl,而不是使用带有“&”的 curl,这将同时安排所有的让我们说 10000 个 curl。

    希望对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 有效负载中

    【讨论】:

      【解决方案7】:

      2020 年更新:

      Curl 现在可以并行获取多个网站:

      curl --parallel --parallel-immediate --parallel-max 3 --config websites.txt
      

      websites.txt 文件:

      url = "website1.com"
      url = "website2.com"
      url = "website3.com"
      

      【讨论】:

      • 在这种情况下 POST 数据如何工作?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多