Node.js批量检测40k企业链接有效性遇问题求解决方案
批量检测企业链接有效性并处理500状态码的解决方案
问题分析
原脚本存在两个核心问题:
- 文件写入异常:
request是异步操作,循环会快速触发所有请求,而out.end()在所有请求完成前执行,导致写入流提前关闭,数据无法全部写入。 ECONNRESET错误:短时间内发起40000个并发请求,超出目标服务器连接限制,被强制断开连接。
优化方案
1. 改用现代HTTP库并控制并发数
request库已停止维护,建议使用axios或node-fetch,同时通过并发控制避免请求过载,比如用p-limit限制同时发起的请求数量。
2. 正确处理文件写入时机
确保所有请求完成后再写入文件,避免因异步操作导致流提前关闭。
3. 完善错误处理和状态码判断
原脚本的else分支会捕获所有非200/30x/401的状态码,需精准判断500状态码再写入文件,避免误操作。
优化后完整代码
import axios from 'axios'; import fs from 'fs/promises'; import pLimit from 'p-limit'; import { tickets } from './tickets.js'; // 限制并发数,可根据服务器承受能力调整(示例设为10) const limit = pLimit(10); const failedTickets = []; async function checkTicket(ticket) { const url = `https://numfin.com/uk/${ticket}/overview`; try { const response = await axios.get(url, { timeout: 5000, // 设置请求超时,避免挂起 maxRedirects: 0 // 禁用自动重定向,手动处理3xx状态码 }); console.log(`${url} is alive!!`); } catch (error) { if (error.response) { const status = error.response.status; switch (status) { case 301: case 302: console.log(`${url} is redirecting us!!`); break; case 401: console.log(`Unauthorized to access ${url}`); break; case 500: console.log(`${url} is dead!!`); failedTickets.push(ticket); break; default: console.log(`${url} returned status ${status}`); } } else if (error.code === 'ECONNRESET') { console.log(`Connection reset for ${url}, retrying...`); // 针对连接重置错误添加重试,提升检测准确性 await checkTicket(ticket); } else { console.log(`Error accessing ${url}: ${error.message}`); } } } async function main() { // 批量执行带并发限制的请求 await Promise.all(tickets.map(ticket => limit(() => checkTicket(ticket)))); // 所有请求完成后统一写入文件 await fs.writeFile('failed_tickets.txt', failedTickets.join('\n'), 'utf8'); console.log(`Done! ${failedTickets.length} failed tickets saved to failed_tickets.txt`); } main().catch(err => console.error('Main process error:', err));
关键优化说明
- 并发控制:通过
p-limit限制同时请求数,避免服务器因过载拒绝连接,解决ECONNRESET问题。 - 异步流程管理:使用
async/await替代回调函数,代码逻辑更清晰,确保所有请求完成后再执行文件写入操作。 - 精准状态码判断:明确仅捕获500状态码的情况,避免将其他错误状态的企业名称误写入文件。
- 超时与重试:设置请求超时时间,对连接重置错误添加重试机制,提升检测的准确性和稳定性。
- 文件写入时机:所有请求处理完成后统一写入文件,彻底解决原脚本中写入流提前关闭的问题。
内容的提问来源于stack exchange,提问作者Vadym Chornyi
相关产品推荐
相关产品推荐

