You need to enable JavaScript to run this app. 如何在Node.js中检测远程IP/服务器负载并筛选CPU负载最低的实例
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中检测远程IP/服务器负载并筛选CPU负载最低的实例

核心实现逻辑

要实现从IP实例列表中选出CPU负载最低的节点,核心链路分为两层:

  • 每个目标节点必须通过可授权访问的接口,暴露自身实时CPU负载指标,不能由调度端跨网络无权限直接钻取远程系统数据
  • 调度端定期并发采集所有节点的负载指标,过滤不可用节点后按负载值升序排序,取排序首位的节点作为调度目标
    核心边界提示:所有跨节点的指标采集操作,必须在节点端配置访问鉴权,避免指标数据泄露。
基于Node.js的全流程实现

第一步:在每个目标节点部署轻量指标暴露服务

每个节点不需要安装复杂监控组件,用内置模块写几行代码即可暴露CPU负载接口,示例代码:

const http = require('http');
const os = require('os');

const server = http.createServer((req, res) => {
  // 简单鉴权:仅校验请求头的固定密钥
  if (req.headers['x-admin-token'] !== '你的自定义鉴权密钥') {
    res.writeHead(403);
    return res.end('forbidden');
  }
  if (req.url === '/metrics/cpu') {
    // 取系统1分钟平均负载,换算为占总CPU核心数的比例,更直观反映实际负载
    const load1 = os.loadavg()[0];
    const totalCores = os.cpus().length;
    const cpuLoad = Number((load1 / totalCores).toFixed(2));
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      nodeIp: '当前节点的绑定IP',
      cpuLoad,
      collectTime: Date.now()
    }));
  }
});
// 服务绑定3000端口
server.listen(3000, '0.0.0.0');

第二步:在调度端实现选点逻辑

调度端就是运行需要分配任务的程序的服务,核心逻辑为:

  • 维护固定的IP实例清单,配置每个节点的指标采集地址
  • 并发发起所有节点的指标请求,设置1秒短超时,超时/请求失败的节点直接标记为不可用
  • 对所有有效节点的CPU负载值做升序排序,取排序第一的节点作为最终选点结果
  • 增加30秒的指标缓存,避免每次请求都全量拉取所有节点的指标,降低网络开销
    对应的核心代码示例:
const nodeIpList = ['192.168.1.10', '192.168.1.11', '192.168.1.12'];
const METRIC_PATH = '/metrics/cpu';
const REQUEST_TIMEOUT = 1000;
const AUTH_TOKEN = '你的自定义鉴权密钥';
// 指标缓存
let metricCache = { expireTime: 0, nodes: [] };

async function pickLowLoadNode() {
  // 命中缓存直接返回
  if (Date.now() < metricCache.expireTime) {
    return metricCache.nodes[0];
  }
  // 并发拉取所有节点的指标
  const collectTasks = nodeIpList.map(async (ip) => {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT);
    try {
      const res = await fetch(`http://${ip}:3000${METRIC_PATH}`, {
        signal: controller.signal,
        headers: { 'x-admin-token': AUTH_TOKEN }
      });
      return await res.json();
    } finally {
      clearTimeout(timeoutId);
    }
  });

  const collectResults = await Promise.allSettled(collectTasks);
  // 过滤请求失败的无效节点
  const validNodes = collectResults
    .filter(item => item.status === 'fulfilled')
    .map(item => item.value);
  
  if (validNodes.length === 0) throw new Error('无可用节点的负载指标');
  // 按CPU负载升序排序
  validNodes.sort((a, b) => a.cpuLoad - b.cpuLoad);
  // 更新缓存,缓存有效期30秒
  metricCache = {
    expireTime: Date.now() + 30 * 1000,
    nodes: validNodes
  };
  return validNodes[0];
}
其他语言/框架的替代实现方案

如果不想用Node.js做全链路开发,可根据现有技术栈选择对应方案:

  • Python 栈:节点端用FastAPI写同样的指标暴露接口,调度端用aiohttp做并发请求,排序逻辑完全一致,无额外依赖
  • 对接现有监控体系:如果节点已经部署了node_exporter等监控采集组件,调度端可以直接拉取暴露的node_load1、cpu_usage指标,不需要重复开发节点端的采集服务
  • 小规模场景轻量实现:如果节点没有暴露HTTP端口,调度端可以通过内置SSH通道远程执行uptime、top -bn1命令提取CPU负载,仅需控制SSH连接的并发数,避免连接耗尽即可

落地注意事项

  • 选点时增加负载差阈值判断:当两个节点的CPU负载差值小于5%时,优先选择之前已经承接过任务的节点,避免频繁调度导致节点负载抖动
  • 增加熔断逻辑:连续3次拉取指标失败的节点,临时移出可用列表,避免将任务调度到宕机节点
  • 控制采集频率:不要过高频率拉取所有节点的指标,避免采集流量本身挤占节点带宽

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 06:45:05