Skip to content

Commit

Permalink
Merge pull request #4 from OVINC-CN/feat_server
Browse files Browse the repository at this point in the history
feat: 增加超时配置&增加数据库连接配置&优化数据库日志
  • Loading branch information
OrenZhang authored Feb 6, 2024
2 parents a0aee39 + 248c4c9 commit 730dba2
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 76 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea
*.log
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ module github.com/OVINC-CN/DevTemplateGo
go 1.20

require (
github.com/gin-contrib/timeout v0.0.6
github.com/gin-gonic/gin v1.9.1
github.com/go-playground/validator/v10 v10.17.0
github.com/google/uuid v1.6.0
github.com/redis/go-redis/v9 v9.4.0
github.com/sirupsen/logrus v1.9.3
golang.org/x/crypto v0.18.0
gorm.io/driver/mysql v1.5.2
gorm.io/gorm v1.25.6
)
Expand All @@ -21,7 +24,6 @@ require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.17.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
Expand All @@ -36,7 +38,6 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/timeout v0.0.6 h1:hRx+DnzQvHAsM7T3SGgIPOOMmyM/Z+szE5IDqf91Mog=
github.com/gin-contrib/timeout v0.0.6/go.mod h1:a4ovm+qCGc+PIK3oF/vm6lC03SG+zZlh+qlDz+7vpnA=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
Expand Down
32 changes: 21 additions & 11 deletions src/configs/db.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package configs

import "github.com/OVINC-CN/DevTemplateGo/src/utils"
import (
"github.com/OVINC-CN/DevTemplateGo/src/utils"
"strconv"
"time"
)

type dbConfigModel struct {
Host string
Port string
User string
Password string
Name string
Host string
Port string
User string
Password string
Name string
MaxConnections int
ConnectionTimeOut time.Duration
SlowThreshold time.Duration
}

var DBConfig = dbConfigModel{
Host: utils.GetEnv("DB_HOST", "127.0.0.1"),
Port: utils.GetEnv("DB_PORT", "3306"),
User: utils.GetEnv("DB_USER", ""),
Password: utils.GetEnv("DB_PASSWORD", ""),
Name: utils.GetEnv("DB_NAME", ""),
Host: utils.GetEnv("DB_HOST", "127.0.0.1"),
Port: utils.GetEnv("DB_PORT", "3306"),
User: utils.GetEnv("DB_USER", ""),
Password: utils.GetEnv("DB_PASSWORD", ""),
Name: utils.GetEnv("DB_NAME", ""),
MaxConnections: utils.StrToInt(utils.GetEnv("DB_MAX_CONNECTIONS", "10")),
ConnectionTimeOut: time.Duration(utils.StrToInt(utils.GetEnv("DB_CONNECTION_TIMEOUT", strconv.Itoa(60*60)))) * time.Second,
SlowThreshold: time.Duration(utils.StrToInt(utils.GetEnv("DB_SLOW_THRESHOLD", strconv.Itoa(100)))) * time.Millisecond,
}
27 changes: 17 additions & 10 deletions src/configs/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,27 @@ import (
"github.com/OVINC-CN/DevTemplateGo/src/utils"
"github.com/sirupsen/logrus"
"os"
"time"
)

type configModel struct {
Debug bool
LogLevel logrus.Level
Port string
AppCode string
AppSecret string
AppCode string
AppSecret string
Debug bool
LogLevel logrus.Level
Port string
RequestTimeout time.Duration
TLSCert string
TLSKey string
}

var Config = configModel{
Debug: utils.StrToBool(utils.GetEnv("DEBUG", "false")),
LogLevel: logrus.InfoLevel,
Port: utils.GetEnv("PORT", ":8000"),
AppCode: os.Getenv("APP_CODE"),
AppSecret: os.Getenv("APP_SECRET"),
AppCode: os.Getenv("APP_CODE"),
AppSecret: os.Getenv("APP_SECRET"),
Debug: utils.StrToBool(utils.GetEnv("DEBUG", "false")),
LogLevel: logrus.InfoLevel,
Port: utils.GetEnv("PORT", ":8000"),
RequestTimeout: time.Duration(utils.StrToInt(utils.GetEnv("REQUEST_TIMEOUT", "10"))) * time.Second,
TLSCert: utils.GetEnv("TLS_CERT", ""),
TLSKey: utils.GetEnv("TLS_KEY", ""),
}
22 changes: 12 additions & 10 deletions src/configs/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package configs
import "github.com/OVINC-CN/DevTemplateGo/src/utils"

type redisConfigModel struct {
Host string
Port string
Password string
DB int
Prefix string
Host string
Port string
Password string
DB int
Prefix string
MaxConnections int
}

var RedisConfig = redisConfigModel{
Host: utils.GetEnv("REDIS_HOST", "127.0.0.1"),
Port: utils.GetEnv("REDIS_PORT", "6379"),
Password: utils.GetEnv("REDIS_PASSWORD", ""),
DB: utils.StrToInt(utils.GetEnv("REDIS_DB", "0")),
Prefix: utils.GetEnv("REDIS_PREFIX", ""),
Host: utils.GetEnv("REDIS_HOST", "127.0.0.1"),
Port: utils.GetEnv("REDIS_PORT", "6379"),
Password: utils.GetEnv("REDIS_PASSWORD", ""),
DB: utils.StrToInt(utils.GetEnv("REDIS_DB", "0")),
Prefix: utils.GetEnv("REDIS_PREFIX", ""),
MaxConnections: utils.StrToInt(utils.GetEnv("REDIS_MAX_CONNECTIONS", "10")),
}
8 changes: 6 additions & 2 deletions src/db/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import (
"github.com/OVINC-CN/DevTemplateGo/src/utils"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"time"
)

var DB *gorm.DB

func InitDBConnection(host, port, user, password, name string) {
func InitDBConnection(host, port, user, password, name string, maxConnections int, connectionTimeout time.Duration, config *gorm.Config) {
var err error
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4", user, password, host, port, name)
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
DB, err = gorm.Open(mysql.Open(dsn), config)
sqlDB, err := DB.DB()
sqlDB.SetMaxOpenConns(maxConnections)
sqlDB.SetConnMaxLifetime(connectionTimeout)
if err != nil {
utils.Logger.Errorf("[InitDBConnectionFailed] %s", err)
} else {
Expand Down
9 changes: 5 additions & 4 deletions src/db/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (

var Redis *redis.Client

func InitRedisConnection(host, port, password string, db int) {
func InitRedisConnection(host, port, password string, db, maxConnections int) {
Redis = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", host, port),
Password: password,
DB: db,
Addr: fmt.Sprintf("%s:%s", host, port),
Password: password,
DB: db,
MaxActiveConns: maxConnections,
})
status := Redis.Ping(context.Background())
utils.Logger.Infof("[InitRedisConnectionSuccess] %T %s", Redis, status)
Expand Down
24 changes: 6 additions & 18 deletions src/middlewares/request.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,26 @@
package middlewares

import (
"bytes"
"encoding/json"
"github.com/OVINC-CN/DevTemplateGo/src/services/account"
"github.com/OVINC-CN/DevTemplateGo/src/utils"
"github.com/gin-gonic/gin"
"io"
"time"
)

func RequestLogger() gin.HandlerFunc {
return func(c *gin.Context) {
// 初始化请求时间
t := time.Now()
// 提取请求体
requestRawData, err := c.GetRawData()
c.Request.Body = io.NopCloser(bytes.NewReader(requestRawData))
if err != nil {
utils.ContextWarningf(c, "[LoadRequestBodyFailed] %s", err)
}
// 执行
c.Next()
// 记录请求耗时
duration := time.Since(t).Milliseconds()
// 解析请求体
var requestJsonData map[string]interface{}
if len(requestRawData) > 0 {
if err = json.Unmarshal(requestRawData, &requestJsonData); err != nil {
requestRawData = []byte("-")
}
} else {
requestRawData = []byte("-")
// 记录用户
username := account.GetContextUser(c).Username
if username == "" {
username = "-"
}
// 记录请求日志
utils.ContextInfof(c, "[RequestLog] (%dms) %s %s %s %d", duration, c.Request.Method, c.Request.URL, requestRawData, c.Writer.Status())
utils.ContextInfof(c, "[RequestLog] %s %s %s %d %d", username, c.Request.Method, c.Request.URL, duration, c.Writer.Status())
}
}
20 changes: 20 additions & 0 deletions src/middlewares/timout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package middlewares

import (
"github.com/OVINC-CN/DevTemplateGo/src/configs"
"github.com/gin-contrib/timeout"
"github.com/gin-gonic/gin"
"net/http"
)

func Timeout() gin.HandlerFunc {
return timeout.New(
timeout.WithTimeout(configs.Config.RequestTimeout),
timeout.WithHandler(func(c *gin.Context) {
c.Next()
}),
timeout.WithResponse(func(c *gin.Context) {
c.AbortWithStatusJSON(http.StatusGatewayTimeout, gin.H{"error": "timeout"})
}),
)
}
4 changes: 2 additions & 2 deletions src/server/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ func setupRouter() (engine *gin.Engine) {
}
engine = gin.New()
engine.RedirectTrailingSlash = false
engine.Use(middlewares.InitLogger(), middlewares.RequestLogger(), middlewares.Authenticate())
engine.Use(middlewares.InitLogger(), middlewares.RequestLogger(), middlewares.Timeout(), middlewares.Authenticate())
// 注册校验器
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
_ = v.RegisterValidation("username", account.UsernameValidator)
}
// Home
homeGroup := engine.Group("/home/")
homeGroup := engine.Group("/")
{
homeGroup.GET("", home.Home)
}
Expand Down
45 changes: 41 additions & 4 deletions src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,56 @@ import (
"github.com/OVINC-CN/DevTemplateGo/src/db"
"github.com/OVINC-CN/DevTemplateGo/src/services/account"
"github.com/OVINC-CN/DevTemplateGo/src/utils"
"gorm.io/gorm"
"runtime"
)

func startServer() {
// init log
utils.InitLogger(configs.Config.Debug, configs.Config.LogLevel)
utils.Logger = utils.InitLogger(
configs.Config.Debug,
configs.Config.LogLevel,
)
utils.DbLogger = utils.InitDBLogger(
configs.Config.Debug,
configs.Config.LogLevel,
configs.DBConfig.SlowThreshold,
)
// init db
db.InitDBConnection(configs.DBConfig.Host, configs.DBConfig.Port, configs.DBConfig.User, configs.DBConfig.Password, configs.DBConfig.Name)
db.InitDBConnection(
configs.DBConfig.Host,
configs.DBConfig.Port,
configs.DBConfig.User,
configs.DBConfig.Password,
configs.DBConfig.Name,
configs.DBConfig.MaxConnections,
configs.DBConfig.ConnectionTimeOut,
&gorm.Config{
Logger: utils.DbLogger,
},
)
migrate()
// init redis
db.InitRedisConnection(configs.RedisConfig.Host, configs.RedisConfig.Port, configs.RedisConfig.Password, configs.RedisConfig.DB)
db.InitRedisConnection(
configs.RedisConfig.Host,
configs.RedisConfig.Port,
configs.RedisConfig.Password,
configs.RedisConfig.DB,
configs.RedisConfig.MaxConnections,
)
// init cpu
threads := runtime.NumCPU()
runtime.GOMAXPROCS(threads)
utils.Logger.Infof("[InitCPUSuccess] Runs on %d CPUs", threads)
// init gin
engine := setupRouter()
if err := engine.Run(configs.Config.Port); err != nil {
var err error
if configs.Config.TLSCert != "" {
err = engine.RunTLS(configs.Config.Port, configs.Config.TLSCert, configs.Config.TLSKey)
} else {
err = engine.Run(configs.Config.Port)
}
if err != nil {
utils.Logger.Infof("[ServerStartFailed] %s", err)
panic(err)
}
Expand Down
Loading

0 comments on commit 730dba2

Please sign in to comment.