Golang备份CLI命令的替代方案或API有哪些
Golang备份CLI命令的替代方案或API有哪些 你好!
我正在尝试使用 Go 语言以编程方式将 InfluxDB 备份到另一台服务器。
我可以通过 Go 的命令行功能实现这一点,如下所示:
cmd := exec.Command(configInfluxDB.InfluxdExeutablePath, "backup", "-portable", "-database", configInfluxDB.Database, "-host", configInfluxDB.HostName+":8088", fileStorePath)
但是,我找不到任何用于相同目的的 Go API 函数。
我想了解类似的函数,它可以接收 path、database、host 和 file path 参数,然后执行备份。
我尝试使用 https://github.com/influxdata/influxdb/blob/master/cmd/influx/backup.go 中定义的后端函数,如下所示:
func newBackupService() (influxdb.BackupService, error) {
return &http.BackupService{
Addr: "http://localhost:8086",
Token: "admin:admin",
}, nil
}
func ConnectToDB(fullFileName string) (*InfluxReader, error) {
// Read InfluxDB instance's properties from an external file.
configInfluxDB, err := loadInfluxProperty(fullFileName)
fmt.Println("hello")
HTTPAddr := fmt.Sprintf("http://%s:%s",configInfluxDB.HostName, configInfluxDB.PortNumber)
c, _ := client.NewHTTPClient(client.HTTPConfig{
Addr: HTTPAddr,
Username: configInfluxDB.UserName,
Password: configInfluxDB.Password,
})
_, _, err = c.Ping(0)
if err != nil {
log.Fatal("Error creating InfluxDB Client: ", err.Error())
}
defer c.Close()
var slash = ""
if string(os.TempDir()[0]) == "C" {
slash = "\\"
} else {
slash = "/"
}
fileStorePath := os.TempDir() + slash + configInfluxDB.Database
fmt.Println(fileStorePath)
ctx := context.Background()
err = os.MkdirAll(fileStorePath, 0777)
if err != nil && !os.IsExist(err) {
fmt.Println("e1")
return nil,err
}
backupService, err := newBackupService()
if err != nil {
fmt.Println("e2")
return nil,err
}
id, backupFilenames, err := backupService.CreateBackup(ctx)
if err != nil {
fmt.Println("e3")
return nil,err
}
fmt.Printf("Backup ID %d contains %d files\n", id, len(backupFilenames))
fmt.Printf("Backup complete")
var files []string
err = filepath.Walk(fileStorePath, visit(&files))
if err != nil {
fmt.Println("Could not store file names:", err)
return nil, err
}
return &InfluxReader{ConfigInfluxDB: configInfluxDB,File: files,Path: fileStorePath}, err
}
运行代码后,输出如下:
hello
(.....some path......)
e3
Failed to establish connection with InfluxDB:2020/05/19 13:47:25 app.Run: 404 page not found
恳请帮助。 谢谢。
更多关于Golang备份CLI命令的替代方案或API有哪些的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang备份CLI命令的替代方案或API有哪些的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据你的代码分析,问题在于你使用了错误的备份服务实现。InfluxDB 2.x 的备份API与1.x不同,且需要正确的认证方式。以下是两种解决方案:
方案一:使用InfluxDB 2.x官方Go客户端(推荐)
package main
import (
"context"
"fmt"
"os"
"github.com/influxdata/influxdb-client-go/v2"
"github.com/influxdata/influxdb-client-go/v2/api"
)
func backupInfluxDB(host, token, org, bucket, backupPath string) error {
// 创建客户端
client := influxdb2.NewClient(host, token)
defer client.Close()
// 获取备份API
backupAPI := client.BackupAPI()
// 创建备份
ctx := context.Background()
backup, err := backupAPI.CreateBackup(ctx, org, bucket)
if err != nil {
return fmt.Errorf("创建备份失败: %v", err)
}
// 下载备份文件
err = backupAPI.DownloadBackup(ctx, backup, backupPath)
if err != nil {
return fmt.Errorf("下载备份失败: %v", err)
}
fmt.Printf("备份成功保存到: %s\n", backupPath)
return nil
}
// 使用示例
func main() {
err := backupInfluxDB(
"http://localhost:8086",
"your-token-here",
"your-org",
"your-bucket",
"/path/to/backup.influxdb",
)
if err != nil {
fmt.Printf("备份失败: %v\n", err)
os.Exit(1)
}
}
方案二:使用InfluxDB 1.x的备份API
如果你的InfluxDB是1.x版本,可以使用以下方法:
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
"github.com/influxdata/influxdb/client/v2"
)
func backupInfluxDBv1(host, username, password, database, backupPath string) error {
// 创建HTTP客户端
httpClient := &http.Client{}
// 构建备份URL
backupURL := fmt.Sprintf("%s/backup?db=%s", host, database)
// 创建请求
req, err := http.NewRequest("GET", backupURL, nil)
if err != nil {
return err
}
// 设置认证
if username != "" && password != "" {
req.SetBasicAuth(username, password)
}
// 执行请求
resp, err := httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// 检查响应状态
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("备份请求失败: %s", resp.Status)
}
// 创建备份文件
outFile, err := os.Create(backupPath)
if err != nil {
return err
}
defer outFile.Close()
// 写入文件
_, err = io.Copy(outFile, resp.Body)
return err
}
// 使用示例
func main() {
err := backupInfluxDBv1(
"http://localhost:8086",
"admin",
"admin",
"mydb",
"/tmp/backup.gz",
)
if err != nil {
fmt.Printf("备份失败: %v\n", err)
os.Exit(1)
}
fmt.Println("备份成功")
}
方案三:使用exec.Command但改进错误处理
如果你坚持使用命令行方式,可以改进你的实现:
package main
import (
"bytes"
"fmt"
"os/exec"
"strings"
)
func backupViaCLI(influxdPath, host, database, backupPath string) error {
// 构建命令参数
args := []string{
"backup",
"-portable",
"-database", database,
"-host", host + ":8088",
backupPath,
}
// 执行命令
cmd := exec.Command(influxdPath, args...)
// 捕获输出
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
// 运行命令
err := cmd.Run()
if err != nil {
return fmt.Errorf("备份命令执行失败: %v\nSTDOUT: %s\nSTDERR: %s",
err, stdout.String(), stderr.String())
}
// 检查输出
output := stdout.String()
if !strings.Contains(output, "backup complete") {
return fmt.Errorf("备份可能未完成: %s", output)
}
return nil
}
// 使用示例
func main() {
err := backupViaCLI(
"/usr/bin/influxd",
"localhost",
"mydatabase",
"/tmp/backup",
)
if err != nil {
fmt.Printf("备份失败: %v\n", err)
} else {
fmt.Println("备份成功")
}
}
关键问题分析
你遇到的404 page not found错误是因为:
- 你使用的
http.BackupService是针对InfluxDB 1.x的 - 你的InfluxDB可能是2.x版本,API路径不同
- 认证方式需要从用户名/密码改为Token
建议先确认你的InfluxDB版本,然后选择对应的API方案。对于生产环境,推荐使用方案一的官方客户端。

