129 lines
2.9 KiB
Go
129 lines
2.9 KiB
Go
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"ego/internal/conf"
|
|||
|
"ego/internal/router"
|
|||
|
"ego/pkg/logger"
|
|||
|
"errors"
|
|||
|
"net/http"
|
|||
|
"os"
|
|||
|
"os/signal"
|
|||
|
"syscall"
|
|||
|
"time"
|
|||
|
|
|||
|
"github.com/gin-gonic/gin"
|
|||
|
"go.uber.org/zap"
|
|||
|
)
|
|||
|
|
|||
|
// @title EGO API
|
|||
|
// @version 1.0
|
|||
|
// @description EGO 系统 API 文档
|
|||
|
// @termsOfService http://swagger.io/terms/
|
|||
|
// @contact.name API Support
|
|||
|
// @contact.url http://www.swagger.io/support
|
|||
|
// @contact.email support@swagger.io
|
|||
|
// @license.name Apache 2.0
|
|||
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
|||
|
// @host 127.0.0.1:3000
|
|||
|
// @BasePath /
|
|||
|
// @securityDefinitions.apikey BearerAuth
|
|||
|
// @in header
|
|||
|
// @name Authorization
|
|||
|
|
|||
|
func main() {
|
|||
|
// 从配置文件读取配置
|
|||
|
if err := conf.Init(); err != nil {
|
|||
|
logger.Error(nil, "配置初始化失败", zap.Error(err))
|
|||
|
os.Exit(1)
|
|||
|
}
|
|||
|
|
|||
|
// 设置 gin 模式
|
|||
|
ginMode := getGinMode()
|
|||
|
gin.SetMode(ginMode)
|
|||
|
logger.Info(nil, "Gin模式设置完成", zap.String("mode", ginMode))
|
|||
|
|
|||
|
// 创建路由
|
|||
|
engine := router.NewRouter()
|
|||
|
|
|||
|
// 获取服务端口
|
|||
|
port := getServerPort()
|
|||
|
|
|||
|
// 创建HTTP服务器
|
|||
|
server := &http.Server{
|
|||
|
Addr: port,
|
|||
|
Handler: engine,
|
|||
|
ReadTimeout: 15 * time.Second,
|
|||
|
WriteTimeout: 15 * time.Second,
|
|||
|
IdleTimeout: 60 * time.Second,
|
|||
|
}
|
|||
|
|
|||
|
// 在goroutine中启动服务器
|
|||
|
go func() {
|
|||
|
logger.Info(nil, "服务器启动中...", zap.String("addr", port))
|
|||
|
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|||
|
logger.Error(nil, "服务器启动失败", zap.Error(err))
|
|||
|
os.Exit(1)
|
|||
|
}
|
|||
|
}()
|
|||
|
|
|||
|
logger.Info(nil, "服务器启动成功", zap.String("addr", port))
|
|||
|
|
|||
|
// 等待中断信号来优雅地关闭服务器
|
|||
|
quit := make(chan os.Signal, 1)
|
|||
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|||
|
<-quit
|
|||
|
|
|||
|
logger.Info(nil, "收到关闭信号,开始优雅关闭服务器...")
|
|||
|
|
|||
|
// 创建一个5秒超时的context
|
|||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|||
|
defer cancel()
|
|||
|
|
|||
|
// 优雅关闭HTTP服务器
|
|||
|
if err := server.Shutdown(ctx); err != nil {
|
|||
|
logger.Error(nil, "服务器强制关闭", zap.Error(err))
|
|||
|
} else {
|
|||
|
logger.Info(nil, "HTTP服务器已优雅关闭")
|
|||
|
}
|
|||
|
|
|||
|
// 关闭其他资源
|
|||
|
conf.Close()
|
|||
|
|
|||
|
logger.Info(nil, "服务器关闭完成")
|
|||
|
}
|
|||
|
|
|||
|
// getGinMode 获取Gin运行模式
|
|||
|
func getGinMode() string {
|
|||
|
mode := os.Getenv("GIN_MODE")
|
|||
|
if mode == "" {
|
|||
|
mode = gin.ReleaseMode // 默认为生产模式
|
|||
|
}
|
|||
|
|
|||
|
// 验证模式是否有效
|
|||
|
switch mode {
|
|||
|
case gin.DebugMode, gin.ReleaseMode, gin.TestMode:
|
|||
|
return mode
|
|||
|
default:
|
|||
|
logger.Warn(nil, "无效的GIN_MODE,使用默认值",
|
|||
|
zap.String("invalid_mode", mode),
|
|||
|
zap.String("default_mode", gin.ReleaseMode))
|
|||
|
return gin.ReleaseMode
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// getServerPort 获取服务器端口
|
|||
|
func getServerPort() string {
|
|||
|
port := os.Getenv("SERVER_PORT")
|
|||
|
if port == "" {
|
|||
|
port = ":3000" // 默认端口
|
|||
|
}
|
|||
|
|
|||
|
// 确保端口格式正确
|
|||
|
if port[0] != ':' {
|
|||
|
port = ":" + port
|
|||
|
}
|
|||
|
|
|||
|
return port
|
|||
|
}
|