背景与目标

公开的网络节点来源很多,但绝大多数节点要么早已失效,要么延迟低却几乎没有可用带宽。手动一个个验证不现实。NodeSieve 的目标是把"采集 → 筛选 → 产出可用清单"整个流程自动化,定时运行,每次只留下当前真正能用的少量节点。

整体链路

系统是一条五步流水线,全部跑在一台 2核2G 的云服务器上:

  • 采集:并发抓取多个公开来源
  • 解析去重:统一成标准结构,按 类型+地址+端口 去重
  • 延迟初筛:批量测延迟,淘汰超时节点
  • 带宽复筛:对延迟达标的节点做真实下载测速
  • 输出:把达标节点写成一份可用清单

多源并发采集

采集阶段用线程池并发拉取约 26 个来源,配合镜像加速规避直连失败。单轮能汇集约 7000 个原始节点,去重后进入后续筛选。把来源、并发数、镜像地址等都集中在脚本顶部的配置区,调整来源不需要改动逻辑。

两级带宽漏斗

延迟低不等于能下载——免费节点里"延迟 300ms 却下载 0"的情况非常普遍。所以筛选分两级漏斗:

  • 快筛:每个节点只测 1.5 秒,速度过低的直接淘汰
  • 精测:只对快筛通过的少数节点做 5 秒完整测速,按真实速度排序

大部分垃圾节点在快筛阶段就被砍掉,精测只处理少量候选,整轮耗时大幅下降。

多实例并发测速与一个并发坑

测速最初复用同一个测速核心:通过它的全局选择器切到某个节点,再从同一个本地端口下载。延迟测速这样做没问题——它走的是按节点隔离的接口。但带宽测速这样做会出事:多个线程同时切换"同一个全局选择器"、又都从"同一个端口"下载,结果谁最后切换谁生效,所有并发下载其实挤在同一条隧道上,测出来的速度互相串扰、不可复现。

修复办法是改成多个独立的测速实例,每个实例有自己的端口和控制器;实例之间并行、单个实例内部串行处理任务队列。这样既保留了并行的速度,又彻底消除了全局选择器被并发抢占的问题。

为了确认改动正确,我做了一组对照实验:对同一批节点,分别用"单实例串行"和"多实例并行"各测一遍。两者结果一致——有速度的都有、为零的都为零,证明新机制与旧机制等价且不再串扰。

工程踩坑

  • 一个非法节点拖垮整份配置:测速核心遇到无法识别的配置会拒绝加载整份清单,于是加了一步逐个剔除非法项的校验。
  • 端口冲突:测速实例一律使用随机空闲端口,避免固定端口被占用。
  • 输出原子写:先写临时文件再原子重命名,保证清单文件永远不会被读到写了一半的中间状态。
  • 节点生命周期很短:高峰时段一轮能筛出三五个可用已属正常,所以"无结果时不覆盖旧清单"是有意为之。

成果

系统通过定时任务每隔半天自动跑一轮,全程无人值守,稳定产出一份当前可用、按速度排序的节点清单。整套逻辑集中在单个脚本里,配置与流程分离,维护成本很低。