Go语言学习之Go Gin 生产级 flag 启动命令模板

Go Gin 生产级 flag 启动命令模板

核心特点:生产级规范(参数校验、日志提示、容错处理)、支持 4 个常用启动参数(环境、配置路径、端口、调试模式),整合 Viper 配置加载、Gin 启动,包含错误处理和用户提示,直接适配生产环境。

一、完整代码(main.go)

Go 复制代码
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
)

// 全局配置结构体(整合所有配置,适配 Viper 反序列化)
type AppConfig struct {
	Server ServerConfig `mapstructure:"server"`
	MySQL  MySQLConfig  `mapstructure:"mysql"`
	Redis  RedisConfig  `mapstructure:"redis"`
}

type ServerConfig struct {
	Port  string `mapstructure:"port"`  // 端口(可被命令行 flag 覆盖)
	Mode  string `mapstructure:"mode"`  // 运行模式(dev/prod/test)
	Debug bool   `mapstructure:"debug"` // 调试模式(可被命令行 flag 覆盖)
}

type MySQLConfig struct {
	Host     string `mapstructure:"host"`
	Port     int    `mapstructure:"port"`
	Username string `mapstructure:"username"`
	Password string `mapstructure:"password"`
	DBName   string `mapstructure:"dbname"`
}

type RedisConfig struct {
	Addr     string `mapstructure:"addr"`
	Password string `mapstructure:"password"`
	DB       int    `mapstructure:"db"`
}

var (
	conf AppConfig // 全局配置对象
)

// InitFlag 初始化命令行参数(生产级:添加参数校验、提示)
func InitFlag() {
	// 1. 定义命令行参数(4个核心参数,均有默认值,支持--help查看说明)
	// -env:运行环境(dev/prod/test),决定加载对应环境的配置逻辑
	env := flag.String("env", "dev", "运行环境,可选值:dev(开发)、prod(生产)、test(测试)")
	// -c:配置文件路径(支持自定义,默认 ./config 目录下的对应环境配置)
	configPath := flag.String("c", fmt.Sprintf("./config/config.%s.yaml", *env), "配置文件路径(默认:./config/config.{env}.yaml)")
	// -port:服务端口(优先级:命令行 > 配置文件 > 默认值)
	port := flag.Int("port", 0, "服务端口(优先级高于配置文件,默认使用配置文件中server.port)")
	// -debug:是否开启调试模式(优先级:命令行 > 配置文件)
	debug := flag.Bool("debug", false, "是否开启调试模式(优先级高于配置文件,开启后打印详细日志)")

	// 2. 解析命令行参数(必须调用,否则无法获取参数值)
	flag.Parse()

	// 3. 参数校验(生产级关键:避免无效参数启动)
	validEnvs := map[string]bool{"dev": true, "prod": true, "test": true}
	if !validEnvs[*env] {
		log.Fatalf("❌ 无效的运行环境:%s,可选值:dev、prod、test", *env)
	}

	// 4. 加载配置文件(Viper 整合,支持自定义路径)
	viper.SetConfigFile(*configPath)
	if err := viper.ReadInConfig(); err != nil {
		log.Fatalf("❌ 加载配置文件失败:%v,路径:%s", err, *configPath)
	}
	// 反序列化配置到全局结构体
	if err := viper.Unmarshal(&conf); err != nil {
		log.Fatalf("❌ 解析配置文件失败:%v", err)
	}

	// 5. 命令行参数覆盖配置文件(优先级:命令行 > 配置文件)
	if *port != 0 {
		conf.Server.Port = fmt.Sprintf("%d", *port)
	}
	if *debug {
		conf.Server.Debug = *debug
	}
	// 同步环境参数到配置
	conf.Server.Mode = *env

	// 6. 打印启动信息(生产级:方便运维排查)
	log.Printf("✅ 启动参数加载完成:")
	log.Printf("   运行环境:%s", *env)
	log.Printf("   配置路径:%s", *configPath)
	log.Printf("   服务端口:%s", conf.Server.Port)
	log.Printf("   调试模式:%t", conf.Server.Debug)
}

// InitGin 初始化 Gin(生产级:适配环境、调试模式)
func InitGin() *gin.Engine {
	// 根据环境设置 Gin 模式(prod 模式自动关闭调试日志)
	if conf.Server.Mode == "prod" {
		gin.SetMode(gin.ReleaseMode)
	} else {
		gin.SetMode(gin.DebugMode)
	}

	// 初始化 Gin 引擎(调试模式开启详细日志)
	r := gin.Default()
	if conf.Server.Debug {
		r.Use(gin.Logger()) // 强制开启日志(即使是 prod 模式,调试时也能查看)
	}

	// 健康检查接口(生产级必备:用于运维监控)
	r.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"status":  "ok",
			"env":     conf.Server.Mode,
			"port":    conf.Server.Port,
			"version": "1.0.0",
		})
	})

	return r
}

func main() {
	// 1. 初始化命令行参数 + 配置加载
	InitFlag()

	// 2. 初始化 Gin 引擎
	r := InitGin()

	// 3. 启动服务(生产级:处理启动失败错误)
	addr := fmt.Sprintf(":%s", conf.Server.Port)
	log.Printf("🚀 服务启动中,地址:http://127.0.0.1%s", addr)
	if err := r.Run(addr); err != nil {
		log.Fatalf("❌ 服务启动失败:%v", err)
	}
}

二、配套项目结构(生产级规范)

bash 复制代码
项目根目录/
├── config/                  # 配置文件目录(按环境拆分)
│   ├── config.dev.yaml      # 开发环境配置
│   ├── config.prod.yaml     # 生产环境配置
│   └── config.test.yaml     # 测试环境配置
├── main.go                  # 入口文件(上面的完整代码)
└── go.mod                   # 依赖管理

三、配置文件示例(config.dev.yaml)

bash 复制代码
server:
  port: 8080
  mode: dev
  debug: true

mysql:
  host: 127.0.0.1
  port: 3306
  username: root
  password: 123456
  dbname: gin_prod_demo

redis:
  addr: 127.0.0.1:6379
  password: ""
  db: 0

四、生产级启动命令(常用场景)

1. 开发环境(默认,最简启动)

bash 复制代码
go run main.go
# 等价于:go run main.go -env dev -c ./config/config.dev.yaml -debug true

2. 生产环境(指定环境、端口,关闭调试)

bash 复制代码
go run main.go -env prod -c ./config/config.prod.yaml -port 80 -debug false
# 生产环境建议:用编译后的二进制文件启动(更高效)
go build -o gin-demo main.go
./gin-demo -env prod -c ./config/config.prod.yaml -port 80 -debug false

3. 测试环境(指定自定义配置路径)

bash 复制代码
go run main.go -env test -c ./config/test-config.yaml -port 8081

4. 查看帮助(运维友好)

bash 复制代码
Usage of /tmp/go-buildxxxx/gin-demo:
  -c string
        配置文件路径(默认:./config/config.{env}.yaml) (default "./config/config.dev.yaml")
  -debug
        是否开启调试模式(优先级高于配置文件,开启后打印详细日志)
  -env string
        运行环境,可选值:dev(开发)、prod(生产)、test(测试) (default "dev")
  -port int
        服务端口(优先级高于配置文件,默认使用配置文件中server.port)

五、生产级优化点(已集成)

  • 参数优先级:命令行参数 > 配置文件 > 默认值(符合生产习惯,方便临时调整)

  • 参数校验:校验运行环境合法性,避免无效参数导致服务启动失败

  • 日志提示:启动时打印关键参数,方便运维排查、监控

  • 容错处理:配置加载、服务启动失败时,打印详细错误信息并退出,避免静默失败

  • 健康检查:自带 /health 接口,适配运维监控(如 Prometheus、Nginx 健康检查)

  • 环境适配:prod 模式自动切换 Gin 为 ReleaseMode,关闭冗余日志,提升性能

六、依赖安装(直接执行)

bash 复制代码
go get github.com/gin-gonic/gin
go get github.com/spf13/viper
相关推荐
xyq20242 小时前
R语言处理JSON文件的方法详解
开发语言
默 语2 小时前
OpenClaw“养龙虾“热潮降温的深层解析:从技术狂欢到理性回归
android·开发语言·kotlin
平安的平安2 小时前
Python 构建AI多智能体系统:让三个 AI 协作完成复杂任务
开发语言·人工智能·python
Fcy6482 小时前
算法基础详解(4)双指针算法
开发语言·算法·双指针
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的分片简介(14)
数据库·学习·mongodb
golang学习记2 小时前
VS Code官宣:全面支持Rust!
开发语言·vscode·后端·rust
Lucis__2 小时前
Linux系统收官篇:线程学习的一些心得总结
linux·学习·线程
luj_17682 小时前
从R语言想起的,。。。
服务器·c语言·开发语言·经验分享·算法
三道渊2 小时前
C语言:二级指针及void与void*的区别
c语言·开发语言