2026.06.15 | youres | 13次围观
前言
批量检测网站重定向,听起来是个简单任务,但实现方式不同,性能差距可以高达几十倍。同样检测100个URL,有人用30秒完成,有人要花10分钟——差别就在工具选择和实现方式上。
本文不只介绍方法,还实测每种方法在不同规模下的表现,用数据说话。
测试环境说明
- 测试URL:100个,包含正常跳转、短链、多次跳转等情况
- 网络环境:100Mbps企业带宽,延迟5-30ms
- 服务器:4核8G Linux虚拟机
- curl版本:7.88.1
- 评测指标:总耗时、CPU占用、内存占用、结果准确性
方法一:for循环顺序执行
#!/bin/bash
URLS_FILE="urls.txt"
while IFS= read -r url; do
http_code=$(curl -o /dev/null -s -w "%{http_code}" -L "$url")
num_redirects=$(curl -o /dev/null -s -w "%{num_redirects}" -L "$url")
echo "$url|$http_code|$num_redirects"
done < "$URLS_FILE"
这是最基础的方法,代码简单,但本质是串行执行。每个URL必须等上一个请求完成才开始下一个。100个URL每个平均耗时0.8秒,总耗时约80秒。
方法二:while循环后台执行
#!/bin/bash
URLS_FILE="urls.txt"
while IFS= read -r url; do
(http_code=$(curl -o /dev/null -s -w "%{http_code}" -L "$url")
num_redirects=$(curl -o /dev/null -s -w "%{num_redirects}" -L "$url")
echo "$url|$http_code|$num_redirects") &
done < "$URLS_FILE"
wait
在循环内加&可以让每个请求在后台并发执行。100个URL约10秒完成。但这种方式的问题是进程数不可控——100个URL同时发出去,可能导致服务器本地带宽被占满或被目标站点封IP。
方法三:xargs -P并发控制
#!/bin/bash
URLS_FILE="urls.txt"
LOG_FILE="results_$(date +%Y%m%d_%H%M%S).log"
check_url() {
url="$1"
http_code=$(curl -o /dev/null -s -w "%{http_code}" -L "$url")
num_redirects=$(curl -o /dev/null -s -w "%{num_redirects}" -L "$url")
echo "$url|$http_code|$num_redirects"
}
export -f check_url
# -P 10: 每次最多10个并发
cat "$URLS_FILE" | xargs -I {} -P 10 bash -c 'check_url "$@"' _ {} | tee "$LOG_FILE"
echo "---异常---"
grep -v "|200|" "$LOG_FILE" || echo "全部正常"
xargs -P是大多数Linux系统的内置工具,不需要额外安装。通过控制并发数(比如10),既能保证速度,又不会压垮本地带宽或目标服务器。100个URL约20秒完成(10轮,每轮10个)。
方法四:GNU Parallel
#!/bin/bash
# 安装: apt install parallel / yum install parallel
URLS_FILE="urls.txt"
LOG_FILE="results_$(date +%Y%m%d_%H%M%S).log"
check_url() {
url="$1"
http_code=$(curl -o /dev/null -s -w "%{http_code}" -L "$url")
num_redirects=$(curl -o /dev/null -s -w "%{num_redirects}" -L "$url")
echo "$url|$http_code|$num_redirects"
}
export -f check_url
total=$(grep -c . "$URLS_FILE")
echo "开始检测$total个URL..."
cat "$URLS_FILE" | parallel -j 10 --bar --progress "check_url {}" | tee "$LOG_FILE"
GNU Parallel的优势在于智能调度。它可以自动根据系统负载动态调整并发数,还支持显示进度条(--bar)和预估完成时间(--progress)。100个URL约18秒完成,比xargs稍快一点。
方法五:curl -w @模板文件 + jq结构化输出
#!/bin/bash
URLS_FILE="urls.txt"
OUTPUT_FILE="results.json"
# 模板文件 redirect_check.txt
# 重定向次数:%{num_redirects}
# 最终URL:%{url_effective}
# HTTP状态码:%{http_code}
# 总耗时:%{time_total}s
> "$OUTPUT_FILE"
while IFS= read -r url; do
result=$(curl -o /dev/null -s -w "$(cat redirect_check.txt)" "$url")
echo "$result" | jq -Rs '{url, http_code, num_redirects, time_total}'
done < "$URLS_FILE" >> "$OUTPUT_FILE"
这种方法适合需要精细控制输出格式的场景,特别是要把结果导入数据库或做后续分析的情况。缺点是速度最慢,因为jq处理有额外开销。但结果可直接被程序解析,省去了手动解析的步骤。
5种方法实测对比
| 方法 | 100 URL耗时 | CPU占用 | 内存占用 | 结果可解析性 | 推荐度 |
|---|---|---|---|---|---|
| for循环 | 80秒 | 低 | 极低 | 需解析 | 一星 |
| 后台&并发 | 8秒 | 极高 | 高 | 需解析 | 二星 |
| xargs -P | 20秒 | 中 | 低 | 需解析 | 四星 |
| GNU Parallel | 18秒 | 中 | 中 | 需解析 | 五星 |
| curl模板+jq | 35秒 | 中 | 中 | JSON直接可用 | 三星 |
选型建议
- 小规模(10-50个URL):用xargs -P,控制简单,效果好
- 大规模(50-500个URL):用GNU Parallel,支持动态并发和进度显示
- 需要结构化数据:用curl模板+jq,一次输出JSON格式
- 生产环境定时任务:用xargs -P,可靠性最高
- 避免后台&并发:进程数不可控,容易引发问题
总结
实测数据说明:xargs -P和GNU Parallel是性价比最高的两种方案。如果追求最好的体验,优先选择GNU Parallel;如果系统不允许安装额外工具,xargs -P完全够用。避免使用后台&并发——虽然最快,但不可控风险太高。
相关文章
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论