在 Shell 脚本中控制批量 curl 请求并发,最推荐直接使用 xargs -P 参数或 GNU parallel 工具,配合 curl 的 `--max-time` 设置超时。
该方案适合批量接口测试、数据迁移场景,风险边界在于过高并发可能触发服务端限流或导致本地文件描述符耗尽。
先说结论:通过管道将 URL 列表传给 xargs 或 parallel,利用其内置并发参数限制同时运行的 curl 进程数。
- 适合:批量 HTTP 请求、接口健康检查、数据预热。
- 先准备:整理好待请求的 URL 列表文件,确认 curl 版本支持超时参数。
- 再验证:观察系统负载和网络错误率,确保未触发服务端封禁。
命令速用版
假设 urls.txt 每行一个接口地址,以下命令限制并发数为 10,超时时间为 5 秒。
cat urls.txt | xargs -P 10 -I {} curl -s -o /dev/null -w "%{http_code}\n" `--max-time` 5 {}若需保留响应内容,去掉 -o /dev/null 并重定向输出文件。
为什么会这样
Shell 原生后台任务符 & 无法限制最大并发数量,容易导致资源失控。
直接使用 & 启动循环会将所有请求几乎同时发出,本地端口耗尽或服务端直接拒绝连接。xargs -P 和 GNU parallel 是专门设计用于控制并行任务数量的工具,能在进程层面排队执行,确保同时运行的 curl 进程不超过设定值。
分步处理
第一步:准备 URL 列表文件。
将需要请求的接口地址整理为纯文本,每行一个,保存为 urls.txt。
第二步:选择并发控制工具。
优先使用系统自带的 xargs,若需更复杂调度可安装 GNU parallel。
第三步:设置 curl 超时参数。
必须添加 `--connect-timeout` 和 `--max-time`,防止单个慢请求阻塞并发槽位。
第四步:执行并记录结果。
将 HTTP 状态码输出到日志文件,便于后续统计成功率。
怎么验证是否生效
使用 top 或 htop 命令观察 curl 进程数量是否稳定在设定值附近。
检查日志文件中是否有 curl 错误码 28(超时)或 000(连接失败),确认超时设置已起作用。
监控本地 netstat -n | grep ESTABLISHED 连接数,确认未超出系统文件描述符限制。
常见坑
xargs 默认可能按空格分割参数,URL 含特殊字符时需加 -I {} 或 -d '\n' 指定分隔符。
并发数设置过高可能触发服务端 WAF 防护,导致 IP 被临时封禁。
未处理 curl 退出码会导致脚本误判所有请求成功,需配合 set -e 或检查返回值。
常见问题
curl 的 `--connect-timeout` 和 `--max-time` 有什么区别?
`--connect-timeout` 仅限制建立 TCP 连接的时间,`--max-time` 限制整个请求过程的总时长。
xargs -P 参数在 macOS 和 Linux 上通用吗?
通用,但 macOS 默认 xargs 版本较旧,建议通过 brew 安装 GNU findutils 以获得完整支持。
如何统计批量请求的成功率?
配合 curl -w "%{http_code}\n" 输出状态码,再用 grep -c "200" 统计成功数量。
参考来源
- curl official documentation, "curl man page", https://curl.se/docs/manpage.html
- GNU Findutils, "xargs man page", https://www.gnu.org/software/findutils/manual/html_node/find_html/xargs-invocation.html