You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何bash端口扫描脚本比node-fetch慢300倍?如何优化?

Bash扫描脚本性能低下的原因及优化方案

性能差异的核心原因

1. 进程启动的额外开销

Node.js脚本在单进程内完成所有HTTP请求,node-fetch是进程内的模块调用,无需反复创建新进程。而你的Bash脚本每次循环都会启动一个独立的curl进程,进程的fork/exec、资源分配与销毁会带来大量额外开销——这是两者性能差距的主要来源。

2. localhost与0.0.0.0的解析/连接差异

localhost默认优先尝试IPv6解析(对应::1),如果目标服务仅监听IPv4,curl会先尝试IPv6连接失败,再回退到IPv4,每个请求都会多一次失败的连接尝试,导致总耗时暴增。而0.0.0.0直接指定IPv4,跳过了IPv6的尝试流程。

Node.js的fetch对localhost的解析逻辑更高效,可能默认优先使用IPv4,或者解析/失败回退的耗时远低于curl,因此两者差异不明显。

3. 同步执行的串行瓶颈

你的Bash脚本是串行执行:必须等当前curl完成才能进入下一次循环。而Node.js即使使用await串行调用,单进程内的HTTP处理效率也远高于频繁启动外部进程的Bash。


Bash脚本的优化方案

1. 强制使用IPv4消除解析延迟

给curl添加-4参数,强制走IPv4,避免localhost的IPv6尝试:

for ((port=$port_from; port<=$port_to; port++))
do
  json="$(curl -4 -s http://localhost:$port/config)"
  echo "$json"
done

这能大幅缩小localhost与0.0.0.0的性能差距。

2. 异步并发执行(核心优化)

利用Bash的后台进程(&)让多个curl同时运行,最后用wait等待所有进程完成,彻底打破串行瓶颈:

# 定义处理单个端口的函数
scan_port() {
  local port=$1
  json=$(curl -4 -s http://localhost:$port/config)
  # 输出时带上端口,避免结果混乱
  echo "Port $port: $json"
}

# 批量启动后台进程
for ((port=$port_from; port<=$port_to; port++))
do
  scan_port $port &
done

# 等待所有后台进程完成
wait

这种方式的总耗时会接近单个请求的最长耗时,而非所有请求耗时之和。

3. 复用curl连接(进阶优化)

使用curl的--parallel参数批量处理请求,减少进程启动次数:

# 生成所有请求URL的列表
urls=()
for ((port=$port_from; port<=$port_to; port++))
do
  urls+=("http://localhost:$port/config")
done

# 并行请求,--parallel-max控制并发数
curl -4 -s --parallel --parallel-max 10 "${urls[@]}"

这种方式只用一个curl进程处理所有请求,彻底消除进程启动开销,性能会更接近Node.js的水平。

4. 用Bash内置/dev/tcp替代curl(极端轻量化)

如果不想依赖curl,可以用Bash内置的/dev/tcp直接建立TCP连接,手动构造HTTP请求。但需要自己处理响应解析,适合追求极致轻量化的场景:

scan_port() {
  local port=$1
  # 构造HTTP GET请求
  printf "GET /config HTTP/1.1\r\nHost: localhost:%d\r\nConnection: close\r\n\r\n" $port > /dev/tcp/localhost/$port
  # 读取响应,过滤出JSON部分(假设响应是纯JSON或在Body中)
  response=$(cat < /dev/tcp/localhost/$port)
  json=$(echo "$response" | awk 'BEGIN{flag=0} /^\r$/ {flag=1; next} flag==1 {print}')
  echo "Port $port: $json"
}

for ((port=$port_from; port<=$port_to; port++))
do
  scan_port $port &
done
wait

注意:这种方式需要处理连接超时、响应格式等问题,复杂度较高。


内容的提问来源于stack exchange,提问作者BoldSheep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:16:25