生产环境配置 #
一、生产环境概述 #
1.1 生产环境要求 #
| 要求 | 说明 |
|---|---|
| 高可用 | 服务稳定运行 |
| 高性能 | 快速响应请求 |
| 安全性 | 防止攻击和数据泄露 |
| 可监控 | 实时监控和告警 |
1.2 配置管理 #
text
开发环境 → 测试环境 → 预发布环境 → 生产环境
二、配置管理 #
2.1 环境变量 #
go
type Config struct {
Server ServerConfig
Database DatabaseConfig
Redis RedisConfig
JWT JWTConfig
}
type ServerConfig struct {
Port int
Mode string
ReadTimeout int
WriteTimeout int
}
func LoadConfig() *Config {
return &Config{
Server: ServerConfig{
Port: getEnvInt("SERVER_PORT", 8080),
Mode: getEnv("GIN_MODE", "release"),
ReadTimeout: getEnvInt("READ_TIMEOUT", 10),
WriteTimeout: getEnvInt("WRITE_TIMEOUT", 10),
},
Database: DatabaseConfig{
Host: getEnv("DB_HOST", "localhost"),
Port: getEnvInt("DB_PORT", 3306),
User: getEnv("DB_USER", "root"),
Password: getEnv("DB_PASSWORD", ""),
Name: getEnv("DB_NAME", "gin_demo"),
},
}
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intVal, err := strconv.Atoi(value); err == nil {
return intVal
}
}
return defaultValue
}
2.2 配置文件 #
yaml
server:
port: 8080
mode: release
read_timeout: 10
write_timeout: 10
database:
host: ${DB_HOST}
port: ${DB_PORT}
user: ${DB_USER}
password: ${DB_PASSWORD}
name: ${DB_NAME}
max_idle_conns: 10
max_open_conns: 100
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
password: ${REDIS_PASSWORD}
db: 0
jwt:
secret: ${JWT_SECRET}
expire_time: 3600
log:
level: info
output: ./logs/app.log
三、性能优化 #
3.1 服务器配置 #
go
func main() {
r := gin.New()
// 生产模式
gin.SetMode(gin.ReleaseMode)
srv := &http.Server{
Addr: ":8080",
Handler: r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
MaxHeaderBytes: 1 << 20,
}
srv.ListenAndServe()
}
3.2 连接池配置 #
go
func initDB(config *DatabaseConfig) *gorm.DB {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
config.User, config.Password, config.Host, config.Port, config.Name)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
sqlDB, _ := db.DB()
// 连接池配置
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
sqlDB.SetConnMaxLifetime(time.Hour)
sqlDB.SetConnMaxIdleTime(10 * time.Minute)
return db
}
3.3 中间件优化 #
go
func main() {
r := gin.New()
// 只使用必要的中间件
r.Use(gin.Recovery())
// 生产环境不使用Logger
if gin.Mode() != gin.ReleaseMode {
r.Use(gin.Logger())
}
// Gzip压缩
r.Use(gzip.Gzip(gzip.DefaultCompression))
r.Run()
}
四、安全配置 #
4.1 安全中间件 #
go
func SecurityMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 安全头
c.Header("X-Content-Type-Options", "nosniff")
c.Header("X-Frame-Options", "DENY")
c.Header("X-XSS-Protection", "1; mode=block")
c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
c.Next()
}
}
4.2 限流配置 #
go
func RateLimitMiddleware() gin.HandlerFunc {
limiter := rate.NewLimiter(rate.Limit(100), 200)
return func(c *gin.Context) {
if !limiter.Allow() {
c.AbortWithStatusJSON(429, gin.H{
"code": 429,
"message": "请求过于频繁",
})
return
}
c.Next()
}
}
4.3 请求大小限制 #
go
func RequestSizeLimitMiddleware(maxSize int64) gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.ContentLength > maxSize {
c.AbortWithStatusJSON(413, gin.H{
"code": 413,
"message": "请求体过大",
})
return
}
c.Next()
}
}
五、日志配置 #
5.1 结构化日志 #
go
func InitLogger(config *LogConfig) *zap.Logger {
cfg := zap.Config{
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
Development: false,
Encoding: "json",
EncoderConfig: zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
},
OutputPaths: []string{config.Output},
ErrorOutputPaths: []string{"stderr"},
}
logger, _ := cfg.Build()
return logger
}
5.2 日志中间件 #
go
func LoggerMiddleware(logger *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
c.Next()
logger.Info("request",
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Int("status", c.Writer.Status()),
zap.Duration("latency", time.Since(start)),
zap.String("client_ip", c.ClientIP()),
)
}
}
六、监控告警 #
6.1 Prometheus监控 #
go
import "github.com/gin-contrib/prometheus"
func main() {
r := gin.New()
p := prometheus.NewPrometheus("gin")
p.Use(r)
r.Run()
}
6.2 健康检查 #
go
func setupHealthCheck(r *gin.Engine, db *gorm.DB, redis *redis.Client) {
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
r.GET("/ready", func(c *gin.Context) {
// 检查数据库
sqlDB, _ := db.DB()
if err := sqlDB.Ping(); err != nil {
c.JSON(503, gin.H{"ready": false, "error": "database not ready"})
return
}
// 检查Redis
if _, err := redis.Ping().Result(); err != nil {
c.JSON(503, gin.H{"ready": false, "error": "redis not ready"})
return
}
c.JSON(200, gin.H{"ready": true})
})
}
6.3 指标收集 #
go
var (
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
},
[]string{"method", "path", "status"},
)
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration in seconds",
Buckets: []float64{.001, .005, .01, .05, .1, .5, 1, 5},
},
[]string{"method", "path"},
)
)
func init() {
prometheus.MustRegister(requestCounter)
prometheus.MustRegister(requestDuration)
}
七、部署配置 #
7.1 Systemd服务 #
ini
[Unit]
Description=Gin Application
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/gin-app
ExecStart=/opt/gin-app/main
Restart=always
RestartSec=5
Environment="GIN_MODE=release"
Environment="DB_HOST=localhost"
Environment="DB_PORT=3306"
[Install]
WantedBy=multi-user.target
7.2 Nginx配置 #
nginx
upstream gin_app {
server 127.0.0.1:8080;
keepalive 32;
}
server {
listen 80;
server_name example.com;
# HTTPS重定向
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://gin_app;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /metrics {
proxy_pass http://gin_app;
allow 10.0.0.0/8;
deny all;
}
}
八、总结 #
8.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 配置管理 | 使用环境变量 |
| 性能优化 | 连接池、超时配置 |
| 安全加固 | 安全头、限流 |
| 监控告警 | Prometheus、健康检查 |
8.2 最佳实践 #
| 实践 | 说明 |
|---|---|
| 环境变量 | 敏感信息使用环境变量 |
| 日志 | 结构化日志输出 |
| 监控 | 实时监控和告警 |
| 备份 | 定期备份数据 |
8.3 下一步 #
现在你已经掌握了生产环境配置,接下来让我们学习 RESTful API,开始实战项目!
最后更新:2026-03-28