for i in {1..42} do wget "https://www.example.com/page$i.html" done
我听说过使用xargs,但我不知道任何关于这一点,手册页是非常混乱。有任何想法吗?甚至可以并行地做到这一点吗?有没有另一种方式我可以去攻击这个?
优点是xargs将正常同步,没有额外的工作。这意味着您可以安全地访问下载的文件(假设没有发生错误)。一旦xargs退出,所有下载都将完成(或失败),并且你知道退出代码是否一切顺利。这是非常喜欢忙等待睡眠和手动测试完成。
假设URL_LIST是一个包含所有URL的变量(可以在OP的示例中用循环构造,但也可以是手动生成的列表),运行:
echo $URL_LIST | xargs -n 1 -P 8 wget -q
将一次将一个参数(-n 1)传递给wget,并且一次最多执行8个并行wget进程(-P 8)。 xarg在最后一个派生进程完成后返回,这正是我们想要知道的。不需要额外的诡计。
我选择的8个并行下载的“魔术数字”并不是一成不变的,但它可能是一个很好的妥协。 “最大化”一系列下载有两个因素:
一种是填充“电缆”,即利用可用带宽。假设“正常”条件(服务器具有比客户端更多的带宽),这已经是一次或至多两次下载的情况。在这个问题上投入更多的连接只会导致数据包被丢弃和TCP拥塞控制踢入,并且N每个以渐近的1 / N带宽下载到相同的净效果(减去丢弃的数据包,减去窗口大小恢复)。丢弃的分组是在IP网络中发生的正常事情,这是拥塞控制应该如何工作(即使使用单个连接),并且通常影响几乎为零。然而,具有不合理的大量连接放大了这种效果,因此它可以变得明显。在任何情况下,它不会使任何更快。
第二个因素是连接建立和请求处理。这里,在飞行中有几个额外的连接真的有帮助。面临的问题是两次往返的延迟(通常是在相同地理区域内的20-40ms,洲际间的200-300ms)加上服务器实际需要处理请求并推送回复的奇1-2毫秒到插座。这不是很多时间本身,而是乘以几百个/千个请求,它快速累加。拥有从六个到十几个请求在飞行中隐藏大部分或所有的这种延迟(它仍然存在,但因为它重叠,它不总结!)。同时,仅具有少量并发连接不会产生不利影响,例如导致过度拥塞或迫使服务器分叉新进程。