用 Go 采集服务器资源指标:从原理到实践

发布于:2025-09-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

在后端开发或运维工作中,采集服务器资源指标 是个绕不开的需求:

  • 运维要看 CPU、内存、磁盘的使用情况
  • 监控系统要定期上报这些数据
  • 应用程序有时候也需要根据系统负载做限流、弹性伸缩

那么问题来了:用 Go 怎么优雅地采集这些指标呢?


为什么要自己采集指标?

很多人会问:我直接用 top / htop / vmstat 不是就能看了吗?
没错,但这些工具只是给人看的。如果你需要:

  • 代码里自动获取 指标
  • 定期 上报到监控系统(比如 Prometheus、InfluxDB)
  • 日志里记录系统状态

那就需要代码层面的采集。


可以采集哪些指标?

常见的几个维度:

  1. CPU

    • 使用率(user / system / idle)
    • 核心数、逻辑线程数
  2. 内存

    • 总内存、已用内存、空闲内存
    • 使用率(百分比)
  3. 磁盘

    • 分区空间:总大小、已用、剩余
    • 使用率
  4. 网络(进阶)

    • 网卡流量、收发包数

这些指标够你搭建一个轻量级的监控系统了。


用 Go 怎么实现?

Go 有几个常见做法:

  1. 直接调用系统命令
    比如执行 df -hfree -m,然后解析输出。缺点是跨平台不友好。

  2. 调用 /proc 接口(Linux 特有)
    读取 /proc/meminfo/proc/stat/proc/diskstats。这种方式比较底层,适合对接高性能监控。

  3. 用工具库封装
    比如 go-commons/systemutils 就在做这件事:用 Go 封装一层,暴露统一的 API。这样上层代码就不用关心不同系统的细节。


用 go-commons/systemutils 的示例

假设我们要获取磁盘信息,可以这样写:

package main

import (
    "fmt"
    "github.com/Rodert/go-commons/systemutils/diskutils"
)

func main() {
    // 获取根目录磁盘信息
    info, err := diskutils.GetDiskInfo("/")
    if err != nil {
        panic(err)
    }

    fmt.Printf("挂载点: %s\n", info.Path)
    fmt.Printf("总空间: %d GB\n", info.Total/1024/1024/1024)
    fmt.Printf("已使用: %d GB\n", info.Used/1024/1024/1024)
    fmt.Printf("可用空间: %d GB\n", info.Free/1024/1024/1024)
}

输出示例:

挂载点: /
总空间: 100 GB
已使用: 45 GB
可用空间: 55 GB

未来 systemutils 里还会有 cpuutilsmemutils,可以类似这样调用:

cpu := cpuutils.GetCPUUsage()
mem := memutils.GetMemInfo()

如何应用到实际项目?

  1. 日志增强
    在关键操作前后,记录系统资源情况,方便排查问题。

  2. 健康检查
    在 API /health 接口里,返回 CPU/内存/磁盘的占用情况。

  3. 报警监控
    定时采集指标,当 CPU > 90% 或磁盘剩余空间 < 10% 时,发通知到钉钉/Slack。

  4. 资源限流
    根据系统负载动态调整并发数,避免雪崩。


总结

用 Go 采集服务器资源指标并不复杂,关键在于:

  • 选好采集方式(命令行 / proc / 工具库)
  • 保证跨平台兼容性
  • 在业务中善加利用(日志、监控、限流)

如果你不想自己重复造轮子,可以直接试试 go-commons/systemutils,它提供了简单易用的 API,把繁琐的系统调用封装掉。

一句话:
👉 用 Go 采指标,用 go-commons 更轻松。