main.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gin-gonic/gin"
  6. "github.com/spf13/viper"
  7. "go.uber.org/zap"
  8. "go_zh/config"
  9. "go_zh/middleware"
  10. "go_zh/pkg/logger"
  11. "go_zh/router"
  12. "net/http"
  13. "os"
  14. "os/signal"
  15. "syscall"
  16. "time"
  17. )
  18. func main() {
  19. // 设置配置文件路径和名称
  20. viper.SetConfigFile("config.json")
  21. viper.SetConfigType("json") // 明确指定JSON格式
  22. err := viper.ReadInConfig() // 搜索并读取配置文件
  23. if err != nil { // 处理错误
  24. panic("初始化配置失败: " + err.Error())
  25. }
  26. // 初始化日志系统
  27. if err := logger.InitLogger(); err != nil {
  28. panic("初始化日志失败: " + err.Error())
  29. }
  30. // 确保程序退出前刷新日志缓冲区
  31. defer logger.Sync()
  32. //初始化mysql
  33. config.InitMysql()
  34. //初始化redis
  35. config.InitRedis()
  36. // 设置 Gin 模式
  37. gin.SetMode(viper.GetString("app.mode"))
  38. // 初始化Gin引擎
  39. engine := gin.Default()
  40. engine.Use(middleware.GinLoggerMiddleware()) //日志中间件
  41. engine.Use(middleware.GinRecoveryMiddleware()) //recover中间件
  42. engine.Use(middleware.ApiMiddleware()) //api请求中间件
  43. // 设置路由
  44. router.SetupRoutes(engine)
  45. // 启动服务
  46. //_ = engine.Run(":8080")
  47. srv := &http.Server{
  48. Addr: fmt.Sprintf(":%d", viper.GetInt("app.port")),
  49. Handler: engine.Handler(),
  50. }
  51. // 优雅启动和关闭
  52. startServer(srv)
  53. }
  54. // startServer 启动服务器
  55. func startServer(srv *http.Server) {
  56. // 在goroutine中启动服务器
  57. go func() {
  58. zap.L().Info("启动HTTP服务器",
  59. zap.String("address", srv.Addr),
  60. )
  61. if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  62. zap.L().Fatal("启动服务器失败", zap.Error(err))
  63. }
  64. }()
  65. // 等待中断信号
  66. quit := make(chan os.Signal, 1)
  67. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  68. <-quit
  69. zap.L().Info("收到关闭信号,开始优雅关闭...")
  70. // 创建关闭超时上下文
  71. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  72. defer cancel()
  73. // 关闭服务器
  74. if err := srv.Shutdown(ctx); err != nil {
  75. zap.L().Error("服务器关闭失败", zap.Error(err))
  76. }
  77. zap.L().Info("服务器已关闭")
  78. }