全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

Gin 框架热重载配置

热重载让代码修改后自动重新编译运行,极大提升开发效率。

Air 工具

安装 Air

Bash
go install github.com/cosmtrek/air@latest

Air 配置文件

toml
# .air.toml
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
  args_bin = []
  bin = "./tmp/main"
  cmd = "go build -o ./tmp/main ."
  delay = 1000
  exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules"]
  exclude_file = []
  exclude_regex = ["_test.go"]
  exclude_unchanged = false
  follow_symlink = false
  full_bin = ""
  include_dir = []
  include_ext = ["go", "tpl", "tmpl", "html", "json", "yaml", "yml"]
  include_file = []
  kill_delay = "2s"
  log = "build-errors.log"
  poll = false
  poll_interval = 0
  rerun = false
  rerun_delay = 500
  send_interrupt = false
  stop_on_error = false

[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  main_only = false
  time = false

[misc]
  clean_on_exit = true

[screen]
  clear_on_rebuild = false
  keep_scroll = true

运行 Air

Bash
# 在项目目录运行
air

# 使用指定配置文件
air -c .air.toml

# 输出
watching .
watching config
watching handlers
watching middleware
building...
running...

Air 工作流程

Bash
1. 监听文件变化
2. 触发重新编译
3. 停止旧进程
4. 启动新进程
5. 显示运行日志

Fresh 工具

安装 Fresh

YAML
go install github.com/gravityblast/fresh@latest

Fresh 配置文件

Bash
# fresh.yaml
root:              .
tmp_path:          ./tmp
build_name:        runner-build
build_log:         runner-build-errors.log
valid_ext:         .go, .tpl, .tmpl, .html, .json, .yaml
ignored_ext:       .test, .md
ignored_paths:     assets, tmp, vendor, node_modules

# Build options
build_options:
    - -race

# 运行参数
run_args: []

运行 Fresh

Bash
fresh

# 或使用配置文件
fresh -c fresh.yaml

Realize 工具

安装 Realize

YAML
go install github.com/tockins/realize@latest

Realize 配置

Go
# .realize.yaml
settings:
  legacy:
    force: false
    interval: 0s
schema:
- name: gin-api
  path: .
  commands:
    run:
      status: true
      method: go run main.go
  watcher:
    paths:
    - /
    extensions:
    - go
    - html
    - json
    ignored:
    paths:
    - vendor

自定义热重载实现

文件监听实现

Go
import (
    "fsnotify"
    "os/exec"
    "os/signal"
    "syscall"
)

type HotReload struct {
    watcher    *fsnotify.Watcher
    cmd        *exec.Cmd
    buildCmd   string
    runCmd     string
}

func NewHotReload() (*HotReload, error) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        return nil, err
    }

    return &HotReload{
        watcher:  watcher,
        buildCmd: "go build -o tmp/main .",
        runCmd:   "./tmp/main",
    }, nil
}

func (h *HotReload) Watch(dirs []string) error {
    for _, dir := range dirs {
        h.watcher.Add(dir)
    }

    // 首次启动
    h.buildAndRun()

    // 监听变化
    for {
        select {
        case event := <-h.watcher.Events:
            if event.Op&fsnotify.Write == fsnotify.Write {
                if strings.HasSuffix(event.Name, ".go") {
                    h.rebuild()
                }
            }
        case err := <-h.watcher.Errors:
            log.Println("Watcher error:", err)
        }
    }
}

func (h *HotReload) buildAndRun() {
    // 编译
    exec.Command("sh", "-c", h.buildCmd).Run()

    // 运行
    h.cmd = exec.Command("sh", "-c", h.runCmd)
    h.cmd.Stdout = os.Stdout
    h.cmd.Stderr = os.Stderr
    h.cmd.Start()
}

func (h *HotReload) rebuild() {
    // 停止旧进程
    if h.cmd != nil && h.cmd.Process != nil {
        h.cmd.Process.Signal(syscall.SIGTERM)
        h.cmd.Wait()
    }

    // 重新编译运行
    h.buildAndRun()
}

使用示例

Go
func main() {
    // 仅开发环境启用热重载
    if os.Getenv("APP_ENV") == "development" {
        hr, err := NewHotReload()
        if err != nil {
            log.Fatal(err)
        }

        dirs := []string{".", "handlers", "middleware", "config"}
        hr.Watch(dirs)
    } else {
        // 生产环境正常运行
        r := gin.Default()
        r.Run(":8080")
    }
}

Gin 开发模式配置

配置区分

Go
func main() {
    // 根据环境设置 Gin 模式
    env := os.Getenv("GIN_MODE")
    if env == "" {
        gin.SetMode(gin.DebugMode)
    } else {
        gin.SetMode(env)
    }

    r := gin.Default()
    setupRoutes(r)

    if gin.Mode() == gin.DebugMode {
        // 开发环境配置
        r.Use(DebugMiddleware())
    }

    r.Run(":8080")
}

Debug 中间件

toml
func DebugMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 开发环境显示详细信息
        log.Printf("[DEBUG] %s %s", c.Request.Method, c.Request.URL.Path)

        c.Next()

        log.Printf("[DEBUG] Status: %d, Latency: %v",
            c.Writer.Status(),
            time.Since(startTime))
    }
}

热重载与配置同步

监听配置文件变化

Go
# .air.toml 扩展配置
[build]
  include_ext = ["go", "tpl", "tmpl", "html", "json", "yaml", "yml", "toml", "env"]
makefile
// 支持配置热更新
func LoadConfig(path string) (*Config, error) {
    // 监听配置文件
    go watchConfig(path)

    // 加载配置
    return parseConfig(path)
}

func watchConfig(path string) {
    watcher, _ := fsnotify.NewWatcher()
    watcher.Add(path)

    for event := <-watcher.Events {
        if event.Op&fsnotify.Write == fsnotify.Write {
            // 重新加载配置
            newConfig := parseConfig(path)
            // 更新全局配置
            updateGlobalConfig(newConfig)
            log.Println("Config updated")
        }
    }
}

Makefile 开发命令

JSON
# Makefile
.PHONY: dev build run clean

dev:
    air

build:
    go build -o bin/gin-api .

run:
    ./bin/gin-api

clean:
    rm -rf tmp/ bin/

test:
    go test ./...

watch-test:
    go test ./... -v -count=1

VSCode 集成

Go
// .vscode/tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "air",
            "type": "shell",
            "command": "air",
            "problemMatcher": [],
            "isBackground": true,
            "presentation": {
                "reveal": "always"
            }
        }
    ]
}

// .vscode/settings.json
{
    "go.testOnSave": true,
    "go.coverOnSave": true
}

热重载注意事项

text
// 需要关闭的资源在热重载时正确处理
func main() {
    // 初始化资源
    db := InitDB()
    cache := InitCache()

    // 优雅关闭(热重载时会调用)
    defer func() {
        db.Close()
        cache.Close()
    }()

    r := gin.Default()
    r.Run(":8080")
}

工具对比

工具优点缺点
Air配置丰富、功能强大启动稍慢
Fresh配置简单、快速功能较少
Realize项目管理已停止维护

注意:热重载仅用于开发环境,生产环境使用标准部署方式。

要点总结

  1. Air 工具:推荐使用,配置丰富、功能强大
  2. 配置文件.air.toml 配置监听目录和文件类型
  3. 自定义实现:使用 fsnotify 监听文件变化
  4. 资源管理:热重载时正确关闭数据库、缓存等资源
  5. 环境区分:仅开发环境启用热重载
  6. IDE集成:VSCode tasks 配置便捷启动

📝 发现内容有误?点击此处直接编辑

← 上一篇 Gin 多环境配置管理
下一篇 → Gin 配置文件加密与安全
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库