Files
backend/internal/handler/swagger.go
lafay 7d1c78f965
Some checks failed
Build / build (push) Successful in 7m52s
Build / build-docker (push) Has been cancelled
refactor: 移除全局单例、修复分层违规、统一错误与响应
2026-06-15 16:40:36 +08:00

92 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"context"
"errors"
"net/http"
"time"
"carrotskin/pkg/redis"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// NewHealthCheck 构造健康检查 handler依赖通过参数注入。
func NewHealthCheck(db *gorm.DB, redisClient *redis.Client) gin.HandlerFunc {
return func(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
defer cancel()
checks := make(map[string]string)
status := "ok"
// 检查数据库
if err := checkDatabase(ctx, db); err != nil {
checks["database"] = "unhealthy: " + err.Error()
status = "degraded"
} else {
checks["database"] = "healthy"
}
// 检查Redis
if err := checkRedis(ctx, redisClient); err != nil {
checks["redis"] = "unhealthy: " + err.Error()
status = "degraded"
} else {
checks["redis"] = "healthy"
}
// 根据状态返回相应的HTTP状态码
httpStatus := http.StatusOK
if status == "degraded" {
httpStatus = http.StatusServiceUnavailable
}
c.JSON(httpStatus, gin.H{
"status": status,
"message": "CarrotSkin API health check",
"checks": checks,
"timestamp": time.Now().Unix(),
})
}
}
// checkDatabase 检查数据库连接
func checkDatabase(ctx context.Context, db *gorm.DB) error {
if db == nil {
return errors.New("数据库未初始化")
}
sqlDB, err := db.DB()
if err != nil {
return err
}
// 使用Ping检查连接
if err := sqlDB.PingContext(ctx); err != nil {
return err
}
// 执行简单查询验证
var result int
if err := db.WithContext(ctx).Raw("SELECT 1").Scan(&result).Error; err != nil {
return err
}
return nil
}
// checkRedis 检查Redis连接
func checkRedis(ctx context.Context, client *redis.Client) error {
if client == nil {
return errors.New("Redis客户端未初始化")
}
// 使用Ping检查连接封装后的方法直接返回error
if err := client.Ping(ctx); err != nil {
return err
}
return nil
}