实战阶段 II:大脑(Master)已经就绪,现在我们需要编写派往各处的“斥候”——Agent。这个 Go 程序将运行在业务服务器上。它必须满足运维的三大铁律:占用低(不能干扰业务)、零依赖(部署时不许安装 Runtime)、自愈强(Master 挂了不能崩)。
学习内容 (30 mins)
1. gopsutil: 采集神器 (10 mins)
1. gopsutil: 采集神器 (10 mins)
如何获取 CPU 使用率?
- Linux 原理: 读取
/proc/stat文件,计算时间片差值。 - Go 原理: 我们不需要自己解析文件。
gopsutil库封装了底层系统调用 (syscall),能跨平台(Linux/Windows/Mac)一致地获取信息。 - 注意事项: 获取 CPU 使用率需要采样时间。比如采样 1 秒,意味着函数会阻塞 1 秒来计算这一秒内的平均负载。
2. Resty: 不只是 HTTP Client (10 mins)
2. Resty: 不只是 HTTP Client (10 mins)
为什么不用 net/http 标准库?
- 标准库: 功能太基础,设置超时、重试、JSON 序列化都要自己写很多代码。
- Resty: 类似 Python 的 Requests 库。它内置了 Automatic Retries (自动重试) 和 Connection Pooling (连接池),这对 Agent 这种需要长期运行的网络程序至关重要。
3. 交叉编译 (Cross Compilation) (10 mins)
3. 交叉编译 (Cross Compilation) (10 mins)
DevOps 的魔法
- 场景: 你在 Mac 上开发,但生产服务器是 Linux,甚至还有几台 Windows。
- 做法: 只需要在编译时指定
GOOS=linux和GOARCH=amd64。 - 结果: Go 编译器会直接生成目标平台机器码。这也是 Go 在运维领域吊打 Python 的核心原因——分发极其容易。
开发任务 (90 mins)
步骤 2: 编写采集与上报逻辑
单文件 代码解释:
main.go 搞定一切。我们将结构体定义、采集逻辑、上报逻辑写在一起。cpu.Percent(1*time.Second, false):采样 1 秒计算 CPU 使用率,会阻塞 1 秒resty.New():创建 HTTP 客户端,支持连接池和自动重试time.NewTicker(5 * time.Second):定时器,每 5 秒触发一次for range ticker.C:阻塞主线程,响应定时器事件
- 轻量级:资源占用小,不影响业务
- 自愈能力:Master 挂了不崩溃,自动重试
- 零依赖:编译后是单个二进制,无需运行时
- 启动 Master: 确保 Pt.1 开发的 Master 服务正在运行
- 运行 Agent:
go run main.go - 观察终端:
- Agent 端显示:
📤 Reporting... ✅ Sent. - Master 端显示:
POST /api/v1/report 201
- Agent 端显示:
- 断在 Master: 关掉 Master 服务。Agent 应该报错
Connection Refused,但不会崩溃退出,而是等待下一次 Ticker。这就是健壮性 - 恢复 Master: 重新启动 Master,Agent 应该自动恢复上报
拓展任务 (30 mins)
配置化改造
任务:目前
MasterURL 是写死的。挑战:改造代码,优先读取环境变量 MASTER_URL。如果没有环境变量,再读取同目录下 config.json 文件。这是标准的云原生应用配置加载顺序。IP 获取难题
任务:如何获取机器的真实 Outbound IP?提示:不要遍历网卡(可能会拿到虚拟 IP)。
今日产出物
monitor_agent_linux- 可直接 scp 到服务器运行的二进制文件main.go- 具备重试和超时控制的 Agent 源码
参考代码
查看参考代码
GitHub 完整代码仓库
Resty 文档
Go 最流行的 HTTP 客户端库
实际应用场景
Sidecar 模式
- 在 K8s 中,Agent 也可以作为 Sidecar 容器和业务容器跑在一个 Pod 里。
- 虽然 Agent 是 Go 写的二进制,但依然可以封装进极小的 Docker 镜像(使用
scratch或alpine基础镜像)。
上一阶段: Master 开发
Day 30 | Pt.1 后端服务开发
下一阶段: 部署交付
Day 30 | Pt.3 毕业交付与总结