目录


框架具体内容可下载git 自己阅读

说明: gin的中间件堪称它的精髓
1.根据gin框架搭建的脚手架 自定义Context头 定义开发结构
2.实现了动态路由 (api开头) 支持版本
3.静态路由也可以匹配动态方法 支持版本
4.添加了一些基础中间件 (logger & JWT & contextKeys & limit & cors等)
5.setting 配置信息设置
6.开发结构分层 (api控制器层、service服务层、dao数据获取逻辑层、model层)
7.jwt-go 实例 & 简单用户验证
8.实现了自定义异步日志 & gorm自定义日志 & TraceId & 链路日志
9.自定义框架 劫持ServeHTTP方法 实现路由和中间件功能 (zhyu目录) 仅供学习

开始

func main() {
	http := servers.NewHttp()
	// 启动gin服务
	router := http.GinNew()
	// 启动http服务
	http.HttpServer(router)
}

httpServer

type Http struct {
}

func NewHttp() *Http {
	return &Http{}
}

// GinNew 初始化gin
func (s *Http) GinNew() *gin.Engine {
	// 启动模式
	gin.SetMode(setting.Server.RunMode)

	if "debug" == setting.Server.RunMode {
		// 日志始终着色
		gin.ForceConsoleColor()
		// 将日志写入文件
		f, _ := os.Create(setting.Server.LogPath + "/see.log")
		gin.DefaultWriter = io.MultiWriter(f, os.Stdout)      // 日志信息
		gin.DefaultErrorWriter = io.MultiWriter(f, os.Stdout) // 错误信息
	}

	// 没有中间件的引擎
	router := gin.New()
	if "debug" == setting.Server.RunMode {
		router.Use(gin.Logger())
	}
	router.Use(gin.Recovery())

	// Content Keys 需要放在路由前面进行初始化
	router.Use(middleware.ContentKeys())
	// 自定义Logger
	router.Use(middleware.Logger())
	go logger.LogHandlerFunc() // 异步处理日志
	// ip白名单
	router.Use(middleware.IpAuth())
	// 定义全局的CORS中间件
	router.Use(middleware.Cors())

	// 静态资源加载,css,js以及资源图片
	//router.StaticFS("/public", http.Dir("./website/static"))
	//router.StaticFile("/favicon.ico", "./resources/favicon.ico")

	// 导入所有模板
	//router.LoadHTMLGlob("website/tpl/*")

	// rate-limit 中间件
	router.Use(middleware.LimitHandler())

	// 注册静态路由
	routes.Routes(router)

	// 注册动态路由 以api开头
	routes.NewAny(router)

	// redis 初始化
	utils.InitRedis()
	// gorm 初始化
	utils.InitDB()

	//routes.Run(":9090") // listen and serve on 0.0.0.0:8080
	return router
}

// HttpServer 启动服务 & 优雅Shutdown(或重启)服务
func (s *Http) HttpServer(router *gin.Engine) {
	srv := &http.Server{
		Addr:         ":" + setting.Server.Port,
		Handler:      router,
		ReadTimeout:  time.Duration(setting.Server.ReadTimeout) * time.Second,
		WriteTimeout: time.Duration(setting.Server.WriteTimeout) * time.Second,
	}
	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// 5秒后优雅Shutdown服务
	quit := make(chan os.Signal)
	signal.Notify(quit, os.Interrupt) //syscall.SIGKILL
	<-quit
	log.Println("Shutdown Server ...")
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(setting.Server.ShutdownTime)*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	select {
	case <-ctx.Done():
	}
	log.Println("Server exiting")
}

设置代理

go env -w GOPROXY=https://goproxy.io,direct

安装gin 及 用到的组件

go get -u github.com/gin-gonic/gin
go get -u github.com/petermattis/goid
go get -u github.com/didip/tollbooth
go get -u gopkg.in/yaml.v2
go get -u github.com/sony/sonyflake
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u gorm.io/gorm/logger
go get -u gorm.io/gorm/schema
go get -u github.com/dgrijalva/jwt-go
go get -u github.com/go-redis/redis/v8

安装验证器

go get -u github.com/go-playground/locales/zh
go get -u github.com/go-playground/universal-translator
go get -u github.com/go-playground/validator/v10
go get -u github.com/go-playground/validator/v10/translations/zh

mysql user 数据结构

zhyu_useridusernamepasswordroleidencryptlastloginiplastlogintimeemailrealnameuseridusernameusername

测试用例 动态路由

测试用例 静态路由