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

能否在Cloud Run容器内获取CPU使用率以实现健康检查?

Cloud Run容器内获取自身CPU使用率的可行方案

你提到的os或systeminformation模块在Cloud Run中无效,是因为这些模块读取的是宿主机的CPU数据,而Cloud Run的容器运行在共享宿主机上,拿到的不是容器自身的使用率。但可以通过读取cgroups虚拟文件系统来获取容器专属的CPU使用数据,以下是具体实现方式:

核心原理:利用cgroups资源隔离机制

Cloud Run通过cgroups限制容器的CPU资源,容器内的/sys/fs/cgroup目录下保存了当前容器的资源使用统计和限制配置,我们可以读取这些文件计算CPU使用率。

实现步骤与代码示例

以下是Node.js环境下的健康检查端点实现:

const fs = require('fs').promises;
const express = require('express');
const app = express();

// 存储上一次的CPU使用数据和时间戳
let prevCpuUsage = BigInt(0);
let prevTimestamp = Date.now();

async function calculateCpuUsage() {
    // 1. 读取容器累计CPU使用时间(纳秒)
    const cpuUsageRaw = await fs.readFile('/sys/fs/cgroup/cpuacct/cpuacct.usage', 'utf8');
    const currentCpuUsage = BigInt(cpuUsageRaw.trim());

    // 2. 获取容器分配的CPU核心数
    const quotaRaw = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_quota_us', 'utf8');
    const periodRaw = await fs.readFile('/sys/fs/cgroup/cpu/cpu.cfs_period_us', 'utf8');
    const cpuQuota = parseInt(quotaRaw.trim(), 10);
    const cpuPeriod = parseInt(periodRaw.trim(), 10);
    const allocatedCores = cpuQuota / cpuPeriod;

    // 3. 计算时间段内的CPU使用率
    const currentTimestamp = Date.now();
    const timeDiffMs = currentTimestamp - prevTimestamp;
    if (timeDiffMs === 0) return 0;

    const cpuUsageDiff = Number(currentCpuUsage - prevCpuUsage);
    // 转换为百分比:(CPU使用纳秒差 / (时间差纳秒 * 核心数)) * 100
    const usagePercent = (cpuUsageDiff / (timeDiffMs * 1e6 * allocatedCores)) * 100;

    // 更新历史数据
    prevCpuUsage = currentCpuUsage;
    prevTimestamp = currentTimestamp;

    return Math.min(usagePercent, 100); // 避免计算误差导致超过100%
}

// 健康检查端点
app.get('/health', async (req, res) => {
    const cpuUsage = await calculateCpuUsage();
    const threshold = 80; // 替换为你需要的X%阈值

    if (cpuUsage > threshold) {
        res.status(500).json({
            status: 'unhealthy',
            cpu_usage: `${cpuUsage.toFixed(2)}%`,
            threshold: `${threshold}%`
        });
    } else {
        res.status(200).json({
            status: 'healthy',
            cpu_usage: `${cpuUsage.toFixed(2)}%`,
            threshold: `${threshold}%`
        });
    }
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
    console.log(`Service running on port ${port}`);
});

关键注意事项

  • 权限问题:Cloud Run默认允许容器读取/sys/fs/cgroup目录,无需额外配置IAM或容器权限
  • 首次调用处理:第一次调用calculateCpuUsage会返回0,建议服务启动后先执行一次预热读取,或者在健康检查逻辑中忽略首次的0值
  • 数据准确性:计算出的是两次读取时间段内的平均CPU使用率,若需要更实时的数值,可以缩短读取间隔

不推荐的方案:Cloud Monitoring指标

Cloud Run会将容器CPU使用率上报到Cloud Monitoring,但这些指标存在1-2分钟的延迟,无法满足健康检查的实时性要求,仅适合用于离线分析或告警场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:13:10