如何通过https并行运行多个curl命令

时间:2014-11-11 02:48:01

标签: bash curl

我尝试使用curl从命令行并行地向运行在localhost上的服务器发出多个请求,但是我很难让它们并行运行。实现这一目标的一种简单方法如下:

for ((i = 0; i < 10; i++))
do
  time curl -k https://localhost:$PORT/fooBar &
done

然而,结果如下:

"my output"
real    0m7.555s
user    0m0.007s
sys     0m0.002s
"my output"
real    0m14.628s
user    0m0.007s
sys     0m0.002s
"my output"
real    0m21.705s
user    0m0.007s
sys     0m0.002s
"my output"
...

尽管服务器是多线程的并且不需要锁定(我知道回答者会怀疑这一点,但考虑我尝试的下一个选项)。因为这似乎是连续发送请求,我尝试了以下内容:

$ time curl -k https://localhost:$PORT/fooBar &
[1] 6780
$ time curl -k https://localhost:$PORT/fooBar &
[2] 6803
$ curl: (35) Unknown SSL protocol error in connection to localhost:<my port>

real    0m1.030s
user    0m0.003s
sys     0m0.002s
"my output"
real    0m7.128s
user    0m0.007s
sys     0m0.002s

为什么这些请求似乎是在带有后台的for循环中执行时串行运行的,以及为什么当我直接从命令行使用后台时出现SSL错误?

编辑:经过进一步的研究,似乎缺乏并行性是因为服务器正在使用scala spray,并且看起来请求由actor在单个线程中处理,即使端点的处理程序由{标记} {1}}。这个观察将这个问题分成两部分。与blockingbash相关的一个事实是curl循环和多个shell单行生成不同的结果(一个导致SSL错误)。解决服务器端缺乏并发性似乎是一个单独的问题。

不幸的是,我不确定如何普遍重现这个问题,因为这是一个私人服务器,但我希望有人可能知道为什么for循环和单行可能产生不同结果

1 个答案:

答案 0 :(得分:3)

在背景声音中启动你的过程听起来很容易并且真的很诱人,但除非你在一个小集合上进行迭代,否则你宁愿不这样做。您可以占用CPU和/或网络,因为您无法控制并发下载进程的数量。

我建议使用xargs

CONCURRENT_PROCESSES=10
seq 1 9 | 
     xargs -P ${CONCURRENT_PROCESSES}  \
         --replace time curl -k https://localhost:{}/fooBar 

xargs&#39; s --replace自动将每个命令调用的参数数量设置为1(-n 1),并用stdin中给出的每个参数替换{}

如果您想要更复杂的方案(例如注册每个单独请求的时间),您可能想要调用包装脚本。