Gin 运行模式

Gin 有三种运行模式:debug、release、test。不同模式有不同的行为,合理使用可以优化性能和调试体验。

设置运行模式

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    gin.SetMode(gin.ReleaseMode)
    
    r := gin.Default()
    
    r.GET("/", func(c *gin.Context) {
        c.String(200, "Hello")
    })
    
    r.Run(":8080")
}

三种模式

const (
    DebugMode   = "debug"
    ReleaseMode = "release"
    TestMode    = "test"
)
  • DebugMode:开发模式,输出详细日志
  • ReleaseMode:生产模式,日志精简,性能更好
  • TestMode:测试模式,用于单元测试

通过环境变量设置

func main() {
    mode := os.Getenv("GIN_MODE")
    if mode == "" {
        mode = gin.DebugMode
    }
    gin.SetMode(mode)
    
    r := gin.Default()
    r.Run(":8080")
}

或者直接设置环境变量:

export GIN_MODE=release
go run main.go

不同模式的行为差异

func main() {
    r := gin.New()
    
    r.Use(gin.Logger())
    r.Use(gin.Recovery())
    
    r.GET("/test", func(c *gin.Context) {
        if gin.Mode() == gin.DebugMode {
            c.JSON(200, gin.H{
                "message": "debug mode",
                "detail":  "详细调试信息",
            })
        } else {
            c.JSON(200, gin.H{
                "message": "release mode",
            })
        }
    })
    
    r.Run(":8080")
}

模式判断

func someFunction() {
    if gin.IsDebugging() {
        log.Println("调试信息...")
    }
    
    switch gin.Mode() {
    case gin.DebugMode:
        log.SetLevel(log.DebugLevel)
    case gin.ReleaseMode:
        log.SetLevel(log.WarnLevel)
    case gin.TestMode:
        log.SetOutput(io.Discard)
    }
}

配置化模式切换

type Config struct {
    Mode string `yaml:"mode"`
}

func main() {
    config := loadConfig()
    
    switch config.Mode {
    case "debug":
        gin.SetMode(gin.DebugMode)
    case "release":
        gin.SetMode(gin.ReleaseMode)
    case "test":
        gin.SetMode(gin.TestMode)
    default:
        gin.SetMode(gin.DebugMode)
    }
    
    r := gin.Default()
    r.Run(":8080")
}

模式对性能的影响

func BenchmarkDebugMode(b *testing.B) {
    gin.SetMode(gin.DebugMode)
    r := gin.New()
    r.GET("/", func(c *gin.Context) { c.String(200, "ok") })
    
    for i := 0; i < b.N; i++ {
        w := httptest.NewRecorder()
        req, _ := http.NewRequest("GET", "/", nil)
        r.ServeHTTP(w, req)
    }
}

func BenchmarkReleaseMode(b *testing.B) {
    gin.SetMode(gin.ReleaseMode)
    r := gin.New()
    r.GET("/", func(c *gin.Context) { c.String(200, "ok") })
    
    for i := 0; i < b.N; i++ {
        w := httptest.NewRecorder()
        req, _ := http.NewRequest("GET", "/", nil)
        r.ServeHTTP(w, req)
    }
}

Release 模式性能更好,因为减少了日志输出。

错误处理差异

func main() {
    gin.SetMode(gin.DebugMode)
    
    r := gin.Default()
    
    r.GET("/panic", func(c *gin.Context) {
        panic("test panic")
    })
    
    r.Run(":8080")
}

Debug 模式下,panic 会返回 HTML 格式的错误页面。Release 模式下,返回简单的文本错误。

测试中使用

func TestAPI(t *testing.T) {
    gin.SetMode(gin.TestMode)
    
    r := gin.New()
    r.GET("/hello", func(c *gin.Context) {
        c.String(200, "hello")
    })
    
    w := httptest.NewRecorder()
    req, _ := http.NewRequest("GET", "/hello", nil)
    r.ServeHTTP(w, req)
    
    assert.Equal(t, 200, w.Code)
    assert.Equal(t, "hello", w.Body.String())
}

禁用控制台颜色

func main() {
    gin.DisableConsoleColor()
    
    r := gin.Default()
    r.Run(":8080")
}

强制控制台颜色

func main() {
    gin.ForceConsoleColor()
    
    r := gin.Default()
    r.Run(":8080")
}

小结

合理使用 Gin 的运行模式:开发环境用 Debug,生产环境用 Release,测试用 Test。Release 模式性能更好,日志更精简。通过环境变量或配置文件控制模式切换,让应用在不同环境下表现最优。