代码拉取完成,页面将自动刷新
/*
@Author: StudentCWZ
@Description:
@File: main
@Software: GoLand
@Project: bluebell
@Date: 2022/3/28 15:54
*/
package main
import (
"bluebell/controller"
"bluebell/dao/mysql"
"bluebell/dao/redis"
"bluebell/logger"
"bluebell/pkg/snowflake"
"bluebell/router"
"bluebell/settings"
"context"
"fmt"
"go.uber.org/zap"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
// Go web 开发较通用的脚手架
// @title bluebell 项目接口文档
// @version 1.0
// @description Go web 开发进阶项目实战 --> 源自李文周
// @contact.name StudentCWZ
// @contact.email 330459539@qq.com
// @license.name Apache 2.0
// @license.url https://www.apache.org/licenses/LICENSE-2.0.html
// @host 127.0.0.1:9090/api/v1
func main() {
// 1. 加载配置
if err := settings.Init(); err != nil {
fmt.Printf("init settings failed, err: %v\n", err)
return
}
// 2. 初始化日志
if err := logger.Init(settings.Conf.LogConfig); err != nil {
fmt.Printf("init settings failed, err: %v\n", err)
return
}
zap.L().Debug("logger init success")
defer func(l *zap.Logger) {
err := l.Sync()
if err != nil {
return
}
}(zap.L())
// 3. 初始化 MySQL
if err := mysql.Init(settings.Conf.MySQLConfig); err != nil {
fmt.Printf("init settings failed, err: %v\n", err)
return
}
defer mysql.Close()
// 4. 初始化 Redis
if err := redis.Init(settings.Conf.RedisConfig); err != nil {
fmt.Printf("init settings failed, err: %v\n", err)
return
}
defer redis.Close()
// 雪花算法:分布式 ID 生成器
if err := snowflake.Init(settings.Conf.SnowFlakeConfig.StartTime, settings.Conf.SnowFlakeConfig.MachineId); err != nil {
fmt.Printf("init snowflake failed, err: %v\n", err)
return
}
// 初始化 gin 框架内置的翻译器
if err := controller.InitTrans("zh"); err != nil {
fmt.Printf("Init validator trans failed, err: %v\n", err)
return
}
// 5. 注册路由
r := router.Setup()
// 6. 启动服务(优雅关机)
srv := &http.Server{
Addr: fmt.Sprintf(":%d", settings.Conf.AppConfig.Port),
Handler: r,
}
go func() {
// 开启一个 goroutine 启动服务
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
// 等待中断信号来优雅地关闭服务器,未关闭服务器操作设置一个 5 秒的超时
quit := make(chan os.Signal, 1) // 创建一个接收信号的通道
// kill 默认会发送 syscall.SIGTERM 信号
// kill -2 发送 syscall.SIGINT 信号,我们常用的 Ctrl + C 就是触发系统 SIGINT 信号
// kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它
// signal.Notify 把收到的 syscall.SIGINT 或者 syscall.SIGTERM 信号转发给 quit
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
<-quit // 阻塞在此,当接收到上述两种信号时才会往下执行
zap.L().Info("Shutdown Server ...")
// 创建一个 5 秒超时 context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 五秒内优雅关闭服务(将未处理完的请求处理完再关闭服务),超出 5 秒就超时退出
if err := srv.Shutdown(ctx); err != nil {
zap.L().Fatal("Server Shutdown: ", zap.Error(err))
}
zap.L().Info("Server exiting ...")
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。