1 Star 0 Fork 0

fkil555 / gin-extend

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
app.go 4.97 KB
一键复制 编辑 原始数据 按行查看 历史
fkil555 提交于 2024-04-26 18:29 . cors
package app
import (
"context"
"fmt"
"net"
"net/http"
"net/http/pprof"
"os"
"os/signal"
"runtime"
"syscall"
"time"
"gitee.com/fkil555/gin-extend/app/middlewares"
"gitee.com/fkil555/gin-extend/client"
"gitee.com/fkil555/gin-extend/conf"
"gitee.com/fkil555/gin-extend/gcontext"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
type GEApp struct {
Gin *gin.Engine
}
func New() (app *GEApp, err error) {
// 加载配置
if err = conf.InitConf(conf.MODE_APP); err != nil {
return
}
// 创建APP
app = &GEApp{}
// 创建Gin
app.initGin()
// 创建客户端
if err = client.InitClients(); err != nil {
return
}
// 注册中间件
app.registerMiddleware()
// 初始化默认路由
app.initDefaultRoute()
return
}
// 启动APP
func (app *GEApp) Run() (err error) {
srv := &http.Server{
Handler: app.Gin,
ReadTimeout: time.Duration(conf.GEConf.AppConfig.ReadTimeout) * time.Millisecond,
WriteTimeout: time.Duration(conf.GEConf.AppConfig.WriteTimeout) * time.Millisecond,
}
//启动server服务
go func() {
if listener, err := net.Listen("tcp", conf.GEConf.AppConfig.Addr); err != nil {
errMsg := fmt.Sprintf("启动server失败:%+v, %+v ", srv, err)
panic(errMsg)
} else {
srv.Serve(listener)
}
}()
// 等待优雅退出命令
app.waitGraceExit(srv)
// 清理关闭一些文件或关闭部分服务
app.close()
return
}
// 闭包ge上下文
func (app *GEApp) WithGEContext(geHandle gcontext.GEHandleFunc) gin.HandlerFunc {
return func(c *gin.Context) {
// 请求超时控制
timeoutCtx, cancelFunc := context.WithTimeout(c, time.Duration(conf.GEConf.AppConfig.HandleTimeout)*time.Millisecond)
defer cancelFunc()
// GE上下文
geCtx := gcontext.GEContext{
Context: timeoutCtx,
Gin: c,
}
// 回调用户
geHandle(&geCtx)
}
}
// 初始化Gin
func (app *GEApp) initGin() {
if conf.GEConf.Debug != 0 {
gin.SetMode(gin.DebugMode) // 调试模式
} else {
gin.SetMode(gin.ReleaseMode) // 生产模式
}
app.Gin = gin.New()
}
// 注册中间件
func (app *GEApp) registerMiddleware() {
// Metadata
app.Gin.Use(middlewares.MetadataMiddleware())
// Recovery崩溃日志(一定要放在最后一位, 否则panic会跳过其下的middleware)
app.Gin.Use(middlewares.Recovery())
// Cors
if conf.GEConf.EnableCors {
app.Gin.Use(middlewares.Cors())
}
}
// 初始化默认路由
func (app *GEApp) initDefaultRoute() {
// 验活接口
app.Gin.GET("/ping", func(c *gin.Context) {
c.String(200, "pong\n")
})
app.Gin.GET("/health", func(c *gin.Context) {
c.String(200, `{"message":"ok","addr":"`+conf.GEConf.AppConfig.Addr+`"}`)
})
// pprof采样接口
if conf.GEConf.Pprof != 0 {
app.registerPprofRoute()
}
// prometheus采集接口
if conf.GEConf.Prometheus != 0 {
app.registerPrometheusRoute()
}
}
// 注册采样接口
func (app *GEApp) registerPprofRoute() {
pprofHandler := func(handler http.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
handler.ServeHTTP(c.Writer, c.Request)
}
}
prefixRouter := app.Gin.Group("/debug/pprof")
{
prefixRouter.GET("/", pprofHandler(pprof.Index))
prefixRouter.GET("/cmdline", pprofHandler(pprof.Cmdline))
prefixRouter.GET("/profile", pprofHandler(pprof.Profile))
prefixRouter.POST("/symbol", pprofHandler(pprof.Symbol))
prefixRouter.GET("/symbol", pprofHandler(pprof.Symbol))
prefixRouter.GET("/trace", pprofHandler(pprof.Trace))
prefixRouter.GET("/allocs", pprofHandler(pprof.Handler("allocs").ServeHTTP))
prefixRouter.GET("/block", pprofHandler(pprof.Handler("block").ServeHTTP))
prefixRouter.GET("/goroutine", pprofHandler(pprof.Handler("goroutine").ServeHTTP))
prefixRouter.GET("/heap", pprofHandler(pprof.Handler("heap").ServeHTTP))
prefixRouter.GET("/mutex", pprofHandler(pprof.Handler("mutex").ServeHTTP))
prefixRouter.GET("/threadcreate", pprofHandler(pprof.Handler("threadcreate").ServeHTTP))
}
}
// 注册prometheus接口:https://prometheus.io/docs/guides/go-application/
func (app *GEApp) registerPrometheusRoute() {
promHandler := promhttp.Handler()
app.Gin.GET("/metrics", func(c *gin.Context) {
promHandler.ServeHTTP(c.Writer, c.Request)
})
}
// 等待优雅退出
func (app *GEApp) waitGraceExit(server *http.Server) {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
fmt.Fprintf(os.Stdout, "%s, 收到信号: %s, 退出倒计时%d毫秒,服务正在退出... \n", time.Now().Format("2006-01-02 15:04:05"), s.String(), conf.GEConf.AppConfig.WaitGraceExit)
ctx, _ := context.WithTimeout(context.TODO(), time.Duration(conf.GEConf.AppConfig.WaitGraceExit)*time.Millisecond)
server.Shutdown(ctx)
return
case syscall.SIGHUP:
default:
}
}
}
// 清理关闭一些文件或关闭部分服务
func (app *GEApp) close() {
client.Close()
}
// 初始化运行环境
func init() {
runtime.GOMAXPROCS(runtime.NumCPU()) // 用满所有核心
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/fkil555/gin-extend.git
git@gitee.com:fkil555/gin-extend.git
fkil555
gin-extend
gin-extend
v0.0.19

搜索帮助

344bd9b3 5694891 D2dac590 5694891