用 Go 采集服务器资源指标:从原理到实践
在后端开发或运维工作中,采集服务器资源指标 是个绕不开的需求:
- 运维要看 CPU、内存、磁盘的使用情况
- 监控系统要定期上报这些数据
- 应用程序有时候也需要根据系统负载做限流、弹性伸缩
那么问题来了:用 Go 怎么优雅地采集这些指标呢?
为什么要自己采集指标?
很多人会问:我直接用 top
/ htop
/ vmstat
不是就能看了吗?
没错,但这些工具只是给人看的。如果你需要:
- 在 代码里自动获取 指标
- 定期 上报到监控系统(比如 Prometheus、InfluxDB)
- 在 日志里记录系统状态
那就需要代码层面的采集。
可以采集哪些指标?
常见的几个维度:
-
CPU
- 使用率(user / system / idle)
- 核心数、逻辑线程数
-
内存
- 总内存、已用内存、空闲内存
- 使用率(百分比)
-
磁盘
- 分区空间:总大小、已用、剩余
- 使用率
-
网络(进阶)
- 网卡流量、收发包数
这些指标够你搭建一个轻量级的监控系统了。
用 Go 怎么实现?
Go 有几个常见做法:
-
直接调用系统命令
比如执行df -h
、free -m
,然后解析输出。缺点是跨平台不友好。 -
调用 /proc 接口(Linux 特有)
读取/proc/meminfo
、/proc/stat
、/proc/diskstats
。这种方式比较底层,适合对接高性能监控。 -
用工具库封装
比如go-commons/systemutils
就在做这件事:用 Go 封装一层,暴露统一的 API。这样上层代码就不用关心不同系统的细节。
用 go-commons/systemutils 的示例
假设我们要获取磁盘信息,可以这样写:
package mainimport ("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
里还会有 cpuutils
、memutils
,可以类似这样调用:
cpu := cpuutils.GetCPUUsage()
mem := memutils.GetMemInfo()
如何应用到实际项目?
-
日志增强
在关键操作前后,记录系统资源情况,方便排查问题。 -
健康检查
在 API/health
接口里,返回 CPU/内存/磁盘的占用情况。 -
报警监控
定时采集指标,当 CPU > 90% 或磁盘剩余空间 < 10% 时,发通知到钉钉/Slack。 -
资源限流
根据系统负载动态调整并发数,避免雪崩。
总结
用 Go 采集服务器资源指标并不复杂,关键在于:
- 选好采集方式(命令行 / proc / 工具库)
- 保证跨平台兼容性
- 在业务中善加利用(日志、监控、限流)
如果你不想自己重复造轮子,可以直接试试 go-commons/systemutils,它提供了简单易用的 API,把繁琐的系统调用封装掉。
一句话:
👉 用 Go 采指标,用 go-commons 更轻松。