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

高频HTTP请求服务器压测实现咨询:Node.js原生http.request方案

针对高并发HTTP负载测试的Node.js优化方案

哥们,你想用Node.js原生http模块实现高并发负载测试的思路是可行的,但你当前的代码存在几个关键问题,会影响并发能力和稳定性,咱们一步步来梳理优化:

你的代码里的潜在问题

  • 多定时器竞态问题:你用for循环创建了100个setInterval,每个间隔设为0,这会让事件循环被大量定时器抢占,而且多个定时器同时判断reqCount,很容易出现多个请求同时发起,导致实际并发量远超你设置的maxConcurrentRequests,瞬间打满资源。
  • 错误处理不完整:你只监听了请求的error事件,但响应对象的错误、请求超时都没处理,会导致失败的请求挂起,占用连接资源。
  • 定时器精度问题:setInterval的实际执行间隔受事件循环影响,高负载下根本达不到“每秒数千次”的精准控制。

优化后的实现方案

咱们换用异步并发池+循环控制的方式,既能精准控制并发数,又能稳定达到高请求量,代码示例如下:

const http = require('http');
// 替换成你的目标服务配置
const config = { hostname: 'your-target-host', port: 80 };
// 最大并发数,根据服务器性能和系统限制调整
const MAX_CONCURRENT = 200;
// 测试持续时间,比如1分钟
const TEST_DURATION = 60 * 1000;

let activeRequests = 0;
let totalRequests = 0;
let failedRequests = 0;

// 生成唯一不重复的路径
function getRandomUniquePath() {
  // 用时间戳+随机字符串保证唯一性
  return `/load-test/${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
}

// 封装单个请求的Promise
function sendSingleRequest() {
  return new Promise((resolve, reject) => {
    activeRequests++;
    totalRequests++;

    const req = http.request({
      hostname: config.hostname,
      port: config.port,
      path: getRandomUniquePath(),
      method: 'GET',
      agent: false, // 禁用连接池,每个请求新建TCP连接
      timeout: 5000 // 设置5秒超时,避免请求挂起
    }, (res) => {
      // 必须消费响应数据,否则会内存泄漏
      res.resume();
      res.on('end', () => {
        activeRequests--;
        resolve();
      });
    });

    // 处理请求错误
    req.on('error', (err) => {
      failedRequests++;
      activeRequests--;
      reject(err);
    });

    // 处理超时
    req.on('timeout', () => {
      failedRequests++;
      activeRequests--;
      req.destroy();
      reject(new Error('Request timed out'));
    });

    req.end();
  });
}

// 主测试逻辑
async function runLoadTest() {
  const testEndTime = Date.now() + TEST_DURATION;

  // 循环发送请求直到测试结束
  while (Date.now() < testEndTime) {
    // 控制并发数,不超过最大值
    if (activeRequests < MAX_CONCURRENT) {
      sendSingleRequest().catch(err => {
        console.error(`请求失败: ${err.message}`);
      });
      // 调整这个间隔可以控制请求速率,比如设为1ms就是每秒约1000次
      await new Promise(resolve => setTimeout(resolve, 1));
    } else {
      // 并发满了就等待1ms再检查
      await new Promise(resolve => setTimeout(resolve, 1));
    }
  }

  // 等待所有活跃请求完成后输出统计
  while (activeRequests > 0) {
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  console.log('\n===== 负载测试结果 =====');
  console.log(`总请求数: ${totalRequests}`);
  console.log(`失败请求数: ${failedRequests}`);
  console.log(`成功率: ${(((totalRequests - failedRequests)/totalRequests)*100).toFixed(2)}%`);
}

// 启动测试
runLoadTest();

额外的优化建议

  • 调整系统资源限制:高并发下Node.js会打开大量TCP连接,Linux系统默认的文件描述符限制(一般是1024)不够用,需要临时调整ulimit -n 65535,或者修改/etc/security/limits.conf永久设置。
  • 考虑专用负载测试工具:如果你的需求是专业级测试,推荐用Artillery、k6这类工具,它们已经封装了并发控制、统计分析、报告生成等功能,比自己写代码高效得多。但如果必须用Node.js原生实现,上面的方案足够稳定。
  • 监控资源使用:测试时可以用process.memoryUsage()和os.cpus()监控内存和CPU负载,避免进程因资源耗尽崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:07:43