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

如何用Node.js实现Redhat CGroup资源统计文件的等效功能

CGroup资源数据说明与Node.js跨平台实现

各CGroup文件的作用

  • /sys/fs/cgroup/cpu/cpuacct.usage:累计该CGroup下所有进程消耗的CPU总时间,单位为纳秒
  • /sys/fs/cgroup/cpu/cpu.cfs_quota_us:CGroup的CPU配额,单位为微秒,值为-1表示无CPU限制
  • /sys/fs/cgroup/cpu/cpu.cfs_period_us:CPU调度周期,单位为微秒,默认值通常为100000(即100ms)
  • /sys/fs/cgroup/memory/memory.usage_in_bytes:CGroup当前占用的内存总量,单位为字节
  • /sys/fs/cgroup/memory/memory.soft_limit_in_bytes:内存软限制,单位为字节;超过该值时系统会尝试回收内存,但不会直接终止进程
  • /sys/fs/cgroup/memory/memory.limit_in_bytes:内存硬限制,单位为字节;超过该值时进程会被OOM Killer终止
  • /sys/fs/cgroup/memory/memory.stat:内存细分统计文件,其中total_rss是进程实际使用的物理内存,total_cache是页缓存占用的内存大小

Node.js跨平台实现方案

CGroup是Linux专属特性,非Linux系统(Windows/macOS)需要通过系统原生命令或Node.js内置模块获取对应数据,以下实现兼容Linux与非Linux环境,并保证输出格式与原命令完全一致:

const fs = require('fs').promises;
const os = require('os');
const path = require('path');

async function getResourceData() {
    if (os.platform() !== 'linux') {
        // 非Linux环境:通过系统API模拟对应格式输出
        const cpuUsage = BigInt(os.uptime() * 1e9).toString();
        const cpuQuota = '-1';
        const cpuPeriod = '100000';
        const memUsage = os.freemem().toString();
        const memSoftLimit = os.totalmem().toString();
        const memHardLimit = os.totalmem().toString();
        const totalRss = Math.floor(os.freemem() * 0.6).toString();
        const totalCache = Math.floor(os.totalmem() - os.freemem()).toString();

        return `${cpuUsage}\n${cpuQuota}\n${cpuPeriod}\n${memUsage}\n${memSoftLimit}\n${memHardLimit}\ntotal_rss ${totalRss}\ntotal_cache ${totalCache}`;
    }

    // Linux环境:直接读取CGroup文件
    const cpuFilePaths = [
        '/sys/fs/cgroup/cpu/cpuacct.usage',
        '/sys/fs/cgroup/cpu/cpu.cfs_quota_us',
        '/sys/fs/cgroup/cpu/cpu.cfs_period_us'
    ];
    const memFilePaths = [
        '/sys/fs/cgroup/memory/memory.usage_in_bytes',
        '/sys/fs/cgroup/memory/memory.soft_limit_in_bytes',
        '/sys/fs/cgroup/memory/memory.limit_in_bytes'
    ];

    let output = '';

    // 读取CPU相关文件
    for (const filePath of cpuFilePaths) {
        try {
            const content = await fs.readFile(filePath, 'utf8');
            output += content.trim() + '\n';
        } catch (err) {
            // 文件不存在时返回默认值(如宿主机无CGroup限制场景)
            output += filePath.includes('quota') ? '-1\n' : '0\n';
        }
    }

    // 读取内存相关文件
    for (const filePath of memFilePaths) {
        try {
            const content = await fs.readFile(filePath, 'utf8');
            output += content.trim() + '\n';
        } catch (err) {
            // 无限制时返回系统总内存
            output += os.totalmem().toString() + '\n';
        }
    }

    // 读取并过滤memory.stat的目标字段
    try {
        const statContent = await fs.readFile('/sys/fs/cgroup/memory/memory.stat', 'utf8');
        const targetLines = statContent.split('\n').filter(line => 
            line.startsWith('total_rss ') || line.startsWith('total_cache ')
        );
        output += targetLines.join('\n');
    } catch (err) {
        // 降级使用系统内存数据模拟
        output += `total_rss ${os.freemem()}\ntotal_cache ${os.totalmem() - os.freemem()}`;
    }

    return output.trim();
}

// 调用示例
getResourceData()
    .then(data => console.log(data))
    .catch(err => console.error('获取资源数据失败:', err));

注意事项

  1. 容器环境适配:Docker等容器的CGroup路径可能不同,可通过读取/proc/self/cgroup文件获取当前进程所属CGroup路径,动态拼接文件路径
  2. 权限问题:确保Node.js进程拥有读取/sys/fs/cgroup下文件的权限
  3. 非Linux优化:可根据实际需求替换非Linux环境的模拟逻辑,比如Windows用wmic命令、macOS用ps命令获取更精准的CPU/内存数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:33:12