如何在CentOS上利用Go语言进行自动化运维
在CentOS上安装Go语言是基础步骤。首先通过wget下载最新版本的Go(如go1.20.linux-amd64.tar.gz),解压至/usr/local目录,然后配置环境变量使系统识别Go命令。编辑~/.bash_profile文件,添加以下内容:
export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
保存后执行source ~/.bash_profile使配置生效。通过go version命令验证安装是否成功。
使用time.Ticker实现周期性任务,通过os/exec包执行df -h命令获取磁盘使用情况,过滤包含/dev/的行(即挂载点设备),定期输出磁盘状态。示例代码:
package main
import (
"fmt"
"os/exec"
"strings"
"time"
)
func checkDiskUsage() {
cmd := exec.Command("df", "-h")
output, err := cmd.Output()
if err != nil {
fmt.Printf("执行df命令失败: %v\n", err)
return
}
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if strings.Contains(line, "/dev/") {
fmt.Println("磁盘状态:", line)
}
}
}
func main() {
ticker := time.NewTicker(5 * time.Minute) // 每5分钟执行一次
defer ticker.Stop()
checkDiskUsage() // 立即执行一次
for range ticker.C {
checkDiskUsage()
}
}
通过filepath.Walk遍历日志目录(如/var/log/myapp),结合time.Now()计算文件的最后修改时间,删除超过7天的.log文件。使用time.Ticker实现每日自动清理:
package main
import (
"fmt"
"os"
"path/filepath"
"time"
)
func cleanupLogs(logDir string, maxAgeDays int) {
now := time.Now()
cutoff := now.AddDate(0, 0, -maxAgeDays) // 计算截止时间(当前时间减maxAgeDays天)
filepath.Walk(logDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() && filepath.Ext(path) == ".log" && info.ModTime().Before(cutoff) {
if err := os.Remove(path); err == nil {
fmt.Printf("已删除过期日志: %s\n", path)
}
}
return nil
})
}
func main() {
for range time.NewTicker(24 * time.Hour).C { // 每日执行一次
cleanupLogs("/var/log/myapp", 7)
}
}
通过systemctl is-active命令检查服务(如myweb)是否处于active状态,若未运行则调用systemctl start命令重启服务。使用time.Ticker实现每30秒监控一次:
package main
import (
"fmt"
"os/exec"
"strings"
"time"
)
func isServiceRunning(serviceName string) bool {
cmd := exec.Command("systemctl", "is-active", serviceName)
output, err := cmd.Output()
return err == nil && strings.TrimSpace(string(output)) == "active"
}
func startService(serviceName string) {
cmd := exec.Command("systemctl", "start", serviceName)
if err := cmd.Run(); err != nil {
fmt.Printf("启动服务 %s 失败: %v\n", serviceName, err)
} else {
fmt.Printf("已启动服务: %s\n", serviceName)
}
}
func monitorService(serviceName string) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for range ticker.C {
if !isServiceRunning(serviceName) {
fmt.Printf("服务 %s 未运行,尝试重启...\n", serviceName)
startService(serviceName)
}
}
}
func main() {
monitorService("myweb") // 替换为目标服务名
}
使用go build命令将脚本编译为可执行文件(如./cleanup-logs.go编译为cleanup-logs),赋予执行权限:
go build -o cleanup-logs cleanup-logs.go
chmod +x cleanup-logs
为了让应用随系统启动并实现状态监控,将其注册为systemd服务。创建服务文件/etc/systemd/system/cleanup-logs.service,内容如下:
[Unit]
Description=Daily Log Cleanup Service
After=network.target
[Service]
Type=simple
ExecStart=/path/to/cleanup-logs
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
执行以下命令启用并启动服务:
systemctl daemon-reload
systemctl enable cleanup-logs
systemctl start cleanup-logs
通过systemctl status cleanup-logs查看服务状态。
虽然systemd已能管理进程,但Supervisor提供更灵活的进程监控(如自动重启崩溃的进程)。安装Supervisor:
yum install epel-release -y
yum install supervisor -y
systemctl start supervisord
systemctl enable supervisord
在/etc/supervisord.d/目录下创建配置文件cleanup-logs.conf:
[program:cleanup-logs]
command=/path/to/cleanup-logs
autostart=true
autorestart=true
stderr_logfile=/var/log/cleanup-logs.err.log
stdout_logfile=/var/log/cleanup-logs.out.log
执行supervisorctl reread和supervisorctl update使配置生效。
if err != nil判断),使用log包或第三方日志库(如logrus、zap)记录结构化日志,便于后续排查问题。goroutine和channel提升效率;对于SSH批量操作,可使用golang.org/x/crypto/ssh库实现无密码登录。viper库)管理配置;定期更新Go版本以修复安全漏洞。