搭建Gin通用框架

Gin Web 開發腳手架技術文檔

項目概述

本項目是一個基于 Gin 框架的 Go Web 開發腳手架模板,提供了完整的項目結構、配置管理、日志記錄、MySQL 和 Redis 數據庫連接等常用功能集成。

項目結構

gindemo/
├── gindemo.exe          # 編譯后的可執行文件
├── go.mod               # Go 模塊定義文件
├── main.go              # 應用程序入口點
├── conf/                # 配置文件目錄
│   ├── config.yaml      # 主配置文件
│   └── dev.yaml         # 開發環境配置文件
├── dao/                 # 數據訪問層
│   ├── mysql/           # MySQL 相關
│   │   └── mysql.go
│   └── redis/           # Redis 相關
│       └── redis.go
├── logger/              # 日志模塊
│   └── logger.go
├── router/              # 路由層
│   └── route.go
└── setting/             # 配置管理└── setting.go

配置文件

name: "ginweb"
mode: "release"
port: 8080
version: "v.0.0.1"
start_time: "2025-09-01"
machine_id: 1log:level: "info"filename: "web_app.log"max_size: 200max_age: 30max_backups: 7mysql:host: 127.0.0.1port: 13306dbname: "ginweb"user: "root"password: "root"max_open_conns: 200max_idle_conns: 50redis:host: 127.0.0.1port: 6379password: ""db: 0pool_size: 100

核心模塊詳解

1. 應用程序入口 (main.go)

package mainimport ("fmt""gindemo/dao/mysql""gindemo/dao/redis""gindemo/logger""gindemo/router""gindemo/setting""os"
)// Go Web 開發通用的腳手架模板
func main() {if len(os.Args) < 2 {fmt.Printf("need config file.eg: conf config.yaml")return}fmt.Println("load config file:", os.Args[1])// 加載配置if err := setting.Init(os.Args[1]); err != nil {fmt.Printf("load config failed, err:%v\n", err)return}//日志if err := logger.Init(setting.Conf.LogConfig, setting.Conf.Mode); err != nil {fmt.Printf("init logger failed, err:%v\n", err)return}// mysqlif err := mysql.Init(setting.Conf.MysqlConfig); err != nil {fmt.Printf("init mysql failed, err:%v\n", err)return}defer mysql.Close()// redisif err := redis.Init(setting.Conf.RedisConfig); err != nil {fmt.Printf("init redis failed, err:%v\n", err)return}defer redis.Close()//注冊路由r := router.SetupRouter(setting.Conf.Mode)err := r.Run(fmt.Sprintf(":%d", setting.Conf.Port))if err != nil {fmt.Printf("start server failed, err:%v\n", err)return}
}

功能特點:

  • 命令行參數驗證,要求指定配置文件路徑
  • 模塊化初始化流程:配置 → 日志 → MySQL → Redis → 路由
  • 完善的錯誤處理和資源清理(defer 關閉數據庫連接)

2. 配置管理模塊 (setting.go)

package settingimport ("fmt""github.com/fsnotify/fsnotify""github.com/spf13/viper"
)type AppConfig struct {Name      string `mapstructure:"name,omitempty"`Mode      string `mapstructure:"mode,omitempty"`Version   string `mapstructure:"version,omitempty"`StartTime string `mapstructure:"start_time,omitempty"`machineId string `mapstructure:"machine_id,omitempty"`Port      int    `mapstructure:"port,omitempty"`*LogConfig   `mapstructure:"log,omitempty"`*MysqlConfig `mapstructure:"mysql,omitempty"`*RedisConfig `mapstructure:"redis,omitempty"`
}type LogConfig struct {Level      string `mapstructure:"level,omitempty"`Filename   string `mapstructure:"filename,omitempty"`MaxSize    int    `mapstructure:"max_size,omitempty"`MaxAge     int    `mapstructure:"max_age,omitempty"`MaxBackups int    `mapstructure:"max_backups,omitempty"`
}
type MysqlConfig struct {Host         string `mapstructure:"host,omitempty"`Port         int    `mapstructure:"port,omitempty"`DB           string `mapstructure:"dbname,omitempty"`User         string `mapstructure:"user,omitempty"`Password     string `mapstructure:"password,omitempty"`MaxOpenConns int    `mapstructure:"max_open_conns,omitempty"`MaxIdleConns int    `mapstructure:"max_idle_conns,omitempty"`
}type RedisConfig struct {Host         string `mapstructure:"host,omitempty"`Port         int    `mapstructure:"port,omitempty"`Password     string `mapstructure:"password,omitempty"`DB           int    `mapstructure:"db,omitempty"`PoolSize     int    `mapstructure:"pool_size,omitempty"`MinIdleConns int    `mapstructure:"min_idle_conns,omitempty"`
}var Conf = new(AppConfig)func Init(filePath string) (err error) {viper.SetConfigFile(filePath)//讀取配置信息err = viper.ReadInConfig()if err != nil {fmt.Printf("viper.ReadInConfig() failed, err:%v\n", err)return}//把讀取到的配置信息反序列化到 Conf 變量中if err := viper.Unmarshal(Conf); err != nil {fmt.Printf("viper.Unmarshal() failed, err:%v\n", err)}viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {fmt.Printf("Config file changed, filename:%s\n", e.Name)if err2 := viper.Unmarshal(Conf); err2 != nil {fmt.Printf("viper.Unmarshal() failed, err:%v\n", err2)}})return
}

功能特點:

  • 使用 viper 庫實現 YAML 配置文件的讀取和解析
  • 支持配置熱加載,文件變更時自動重新加載配置
  • 結構化的配置定義,類型安全

3. 日志模塊 (logger.go)

package loggerimport ("gindemo/setting""net""net/http""net/http/httputil""os""runtime/debug""strings""time""github.com/gin-gonic/gin""go.uber.org/zap""go.uber.org/zap/zapcore""gopkg.in/natefinch/lumberjack.v2"
)var lg *zap.Logger// Init 初始化lg
func Init(cfg *setting.LogConfig, mode string) (err error) {writeSyncer := getLogWriter(cfg.Filename, cfg.MaxSize, cfg.MaxBackups, cfg.MaxAge)encoder := getEncoder()var l = new(zapcore.Level)err = l.UnmarshalText([]byte(cfg.Level))if err != nil {return}var core zapcore.Coreif mode == "dev" {// 進入開發模式,日志輸出到終端consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())core = zapcore.NewTee(zapcore.NewCore(encoder, writeSyncer, l),zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel),)} else {core = zapcore.NewCore(encoder, writeSyncer, l)}lg = zap.New(core, zap.AddCaller())zap.ReplaceGlobals(lg)zap.L().Info("init logger success")return
}func getEncoder() zapcore.Encoder {encoderConfig := zap.NewProductionEncoderConfig()encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoderencoderConfig.TimeKey = "time"encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoderencoderConfig.EncodeDuration = zapcore.SecondsDurationEncoderencoderConfig.EncodeCaller = zapcore.ShortCallerEncoderreturn zapcore.NewJSONEncoder(encoderConfig)
}func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer {lumberJackLogger := &lumberjack.Logger{Filename:   filename,MaxSize:    maxSize,MaxBackups: maxBackup,MaxAge:     maxAge,}return zapcore.AddSync(lumberJackLogger)
}// GinLogger 接收gin框架默認的日志
func GinLogger() gin.HandlerFunc {return func(c *gin.Context) {start := time.Now()path := c.Request.URL.Pathquery := c.Request.URL.RawQueryc.Next()cost := time.Since(start)lg.Info(path,zap.Int("status", c.Writer.Status()),zap.String("method", c.Request.Method),zap.String("path", path),zap.String("query", query),zap.String("ip", c.ClientIP()),zap.String("user-agent", c.Request.UserAgent()),zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),zap.Duration("cost", cost),)}
}// GinRecovery recover掉項目可能出現的panic,并使用zap記錄相關日志
func GinRecovery(stack bool) gin.HandlerFunc {return func(c *gin.Context) {defer func() {if err := recover(); err != nil {// Check for a broken connection, as it is not really a// condition that warrants a panic stack trace.var brokenPipe boolif ne, ok := err.(*net.OpError); ok {if se, ok := ne.Err.(*os.SyscallError); ok {if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {brokenPipe = true}}}httpRequest, _ := httputil.DumpRequest(c.Request, false)if brokenPipe {lg.Error(c.Request.URL.Path,zap.Any("error", err),zap.String("request", string(httpRequest)),)// If the connection is dead, we can't write a status to it.c.Error(err.(error)) // nolint: errcheckc.Abort()return}if stack {lg.Error("[Recovery from panic]",zap.Any("error", err),zap.String("request", string(httpRequest)),zap.String("stack", string(debug.Stack())),)} else {lg.Error("[Recovery from panic]",zap.Any("error", err),zap.String("request", string(httpRequest)),)}c.AbortWithStatus(http.StatusInternalServerError)}}()c.Next()}
}

功能特點:

  • 基于 zap 高性能日志庫
  • 支持日志輪轉(lumberjack)
  • 開發模式同時輸出到文件和控制臺
  • 提供 Gin 框架的日志中間件和異常恢復處理
  • 智能處理 broken pipe 等連接異常

4. MySQL 數據訪問模塊 (mysql.go)

package mysqlimport ("fmt""gindemo/setting"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx"
)var db *sqlx.DBfunc Init(cfg *setting.MysqlConfig) (err error) {dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true&loc=Local", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DB)db, err = sqlx.Connect("mysql", dsn)if err != nil {return}db.SetMaxIdleConns(cfg.MaxIdleConns)db.SetMaxOpenConns(cfg.MaxOpenConns)return
}func Close() {_ = db.Close()
}

功能特點:

  • 使用 sqlx 增強的 MySQL 驅動
  • 支持連接池配置
  • 自動處理時區問題(loc=Local)

5. Redis 數據訪問模塊 (redis.go)

package redisimport ("fmt""gindemo/setting""github.com/go-redis/redis"
)var (client *redis.ClientNil    = redis.Nil
)func Init(cfg *setting.RedisConfig) (err error) {client = redis.NewClient(&redis.Options{Addr:         fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),Password:     cfg.Password,DB:           cfg.DB,PoolSize:     cfg.PoolSize,MinIdleConns: cfg.MinIdleConns,})_, err = client.Ping().Result()if err != nil {return err}return nil
}func Close() {_ = client.Close()
}

功能特點:

  • 使用 go-redis 客戶端庫
  • 支持連接池配置
  • 導出 Nil 錯誤常量便于處理鍵不存在的情況

6. 路由管理模塊 (route.go)

package routerimport ("gindemo/logger""net/http""github.com/gin-gonic/gin"
)func SetupRouter(mode string) *gin.Engine {if mode == gin.ReleaseMode {// gin 設置成發布模式gin.SetMode(gin.ReleaseMode)}router := gin.New()router.Use(logger.GinLogger(), logger.GinRecovery(true))router.GET("/ping", func(c *gin.Context) {c.String(http.StatusOK, "pong")})return router
}

功能特點:

  • 根據運行模式自動設置 Gin 模式
  • 集成 zap 日志中間件和異常恢復
  • 提供健康檢查端點 /ping

啟動和運行

編譯項目

go build -o gindemo.exe main.go

運行項目

./gindemo.exe conf/config.yaml

測試服務

curl http://localhost:8080/ping

配置說明

應用配置

  • name: 應用名稱
  • mode: 運行模式(debug/release/test)
  • port: HTTP 服務監聽端口
  • version: 應用版本號
  • start_time: 啟動時間標識
  • machine_id: 機器標識,用于分布式部署

日志配置

  • level: 日志級別(debug/info/warn/error)
  • filename: 日志文件名
  • max_size: 單個日志文件最大大小(MB)
  • max_age: 日志保留天數
  • max_backups: 最大備份文件數

MySQL 配置

  • 連接參數:主機、端口、數據庫名、用戶名、密碼
  • 連接池:最大打開連接數、最大空閑連接數

Redis 配置

  • 連接參數:主機、端口、密碼、數據庫編號
  • 連接池:連接池大小、最小空閑連接數

擴展開發指南

添加新的配置項

  1. setting.go 的對應配置結構體中添加字段
  2. 在配置文件中添加相應的配置項
  3. 在需要使用的地方通過 setting.Conf 訪問

添加新的路由

router.goSetupRouter 函數中添加新的路由定義:

router.GET("/new-endpoint", func(c *gin.Context) {// 處理邏輯
})

添加業務模塊

  1. 創建新的包目錄
  2. 實現相關功能
  3. main.go 中初始化和集成

總結

這個 Gin Web 開發腳手架提供了一個結構清晰、功能完整的起點,具有以下特點:

  1. 模塊化設計:各功能模塊職責清晰,便于維護和擴展
  2. 配置驅動:所有可變參數都通過配置文件管理
  3. 生產就緒:包含日志、監控、異常處理等生產環境必需功能
  4. 高性能:基于 Gin 和 zap 等高性能庫
  5. 易于擴展:清晰的架構便于添加新功能

該項目適合作為中小型 Web 服務的開發基礎,可根據具體需求進行進一步定制和擴展。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/100484.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/100484.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/100484.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows 平臺下 ffmpeg 硬件編解碼環境查看

環境&#xff1a; 1&#xff0c;nvidia 顯卡 2&#xff0c;驅動安裝 powershell 下 執行如下命令&#xff0c;出現GPU信息 說明驅動安裝正常。 nvidia-smi 3&#xff0c;安裝支持 NVENC 的 FFmpeg &#xff08;1&#xff09;Windows 下 編譯 FFmpeg 需要 CUDA Toolkit &am…

08_多層感知機

1. 單層感知機 1.1 感知機① 線性回歸輸出的是一個實數&#xff0c;感知機輸出的是一個離散的類。1.2 訓練感知機 ① 如果分類正確的話y<w,x>為正數&#xff0c;負號后變為一個負數&#xff0c;max后輸出為0&#xff0c;則梯度不進行更新。 ② 如果分類錯了&#xff0c;y…

安卓實現miniLzo壓縮算法

LZO官方源碼 http://www.oberhumer.com/opensource/lzo 找到miniLZO點擊Dowload miniLZO下載源碼 http://www.oberhumer.com/opensource/lzo/download/minilzo-2.10.tar.gz demo源碼(包含安卓) https://github.com/xzw421771880/MiniLzo_Mobile.git 1.代碼部分 1.1.測試…

如何在ubuntu下用pip安裝aider,解決各種報錯問題

aider中文文檔網站上給出的安裝說明比較簡單&#xff1a; https://aider.doczh.com/docs/install.html 但是在一個干凈的ubuntu環境中按文檔中的命令安裝時&#xff0c;會報錯&#xff0c;經過一番嘗試之后&#xff0c;解決了報錯問題&#xff0c;成功完成了安裝。 成功安裝執…

Kotlin flow詳解

流式數據處理基礎 Kotlin Flow 是基于協程的流式數據處理 API&#xff0c;要深入理解 Flow&#xff0c;首先需要明確流的概念及其處理方式。 流(Stream)如同水流&#xff0c;是一種連續不斷的數據序列&#xff0c;在編程中具有以下核心特征&#xff1a; 數據按順序產生和消費支…

DeepSeek V3 深度解析:MoE、MLA 與 GRPO 的架構革新

簡介 DeepSeek&#xff08;深度求索&#xff09;是一家源自中國的人工智能公司&#xff0c;成立于2023年&#xff0c;總部位于中國杭州。前身是國內量化投資巨頭幻方量化的子公司。公司專注于開發低成本、高性能的AI模型&#xff0c;致力于通過技術創新推動人工智能技術的普惠…

Flask學習筆記(三)--URL構建與模板的使用

一、URL構建url_for()函數對于動態構建特定函數的URL非常有用。 該函數接受函數的名稱作為第一個參數&#xff0c;并接受一個或多個關鍵字參數&#xff0c;每個參數對應于URL的變量部分。from flask import Flask, redirect, url_forapp Flask(__name__)app.route(/admin)def …

Pyside6 + QML - 從官方的例程開始

導言如上所示&#xff0c;登上Qt Pyside6的官方網址&#xff1a;https://doc.qt.io/qtforpython-6/index.html&#xff0c;點擊“Write your first Qt application”的"Start here!"按鈕。 效果&#xff1a;工程代碼&#xff1a; github:https://github.com/q1641293…

Python爬蟲實戰:研究Pandas,構建物聯網數據采集和分析系統

1. 引言 1.1 研究背景 物聯網(Internet of Things, IoT)作為新一代信息技術的重要組成部分,已廣泛應用于智能交通、環境監測、智慧家居等多個領域。據 Gartner 預測,到 2025 年全球物聯網設備數量將達到 750 億臺,產生的數據量將突破 zettabyte 級別。物聯網平臺作為數據…

深度學習入門基石:線性回歸與 Softmax 回歸精講

一、線性回歸&#xff1a;從房價預測看懂 “連續值預測” 邏輯 線性回歸是深度學習的 “敲門磚”&#xff0c;它的核心思想是用線性關系擬合數據規律&#xff0c;解決連續值預測問題—— 比如根據房屋特征估算房價、根據溫度濕度預測降雨量等。 1. 從生活案例到數學模型 拿房價…

GPT-5-Codex CLI保姆級教程:獲取API Key配置與openai codex安裝詳解

朋友們&#xff0c;就在 2025 年 9 月中旬&#xff0c;OpenAI 悄悄扔下了一顆重磅炸彈&#xff1a;GPT-5-Codex。 如果你以為這只是又一次平平無奇的模型升級&#xff0c;那可就大錯特錯了。 我可以這么說&#xff1a;軟件開發的游戲規則&#xff0c;從這一刻起&#xff0c;可能…

基于Spark的用戶實時分析

Spark的最簡安裝 1. 下載并解壓 Spark 首先,我們需要下載 Spark 安裝包。您可以選擇以下方式之一: 方式一:從官網下載(推薦) # 在 hadoop01 節點上執行 cd /home/hadoop/app wget https://archive.apache.org/dist/spark/spark-2.3.1/spark-2.3.1-bin-hadoop2.7.tgz方…

OpenCV 風格遷移、DNN模塊 案例解析及實現

圖像風格遷移是計算機視覺領域極具趣味性的技術之一 —— 它能將普通照片&#xff08;內容圖像&#xff09;與藝術畫作&#xff08;風格圖像&#xff09;的特征融合&#xff0c;生成兼具 “內容輪廓” 與 “藝術風格” 的新圖像。OpenCV 的 DNN&#xff08;深度神經網絡&#x…

MySQL 日志:undo log、redo log、binlog以及MVCC的介紹

一、MySQL 日志&#xff1a;undo log、redo log、binlogundo log&#xff08;回滾日志&#xff09;&#xff1a;是 Innodb 存儲引擎層生成的日志&#xff0c;實現了事務中的原子性&#xff0c;主要用于事務回滾和 MVCC&#xff08;隔離性&#xff09;。 redo log&#xff08;重…

【面板數據】省及地級市農業新質生產力數據集(2002-2025年)

農業新質生產力是以科技創新為核心驅動力&#xff0c;以科技化、數字化、網絡化和智能化為主線&#xff0c;通過技術革命性突破、生產要素創新性配置、產業深度轉型升級&#xff0c;實現農業全要素生產率顯著躍升的先進生產力形態 本數據基于2002-2025年各省政府工作報告中關于…

20250917在榮品RD-RK3588-MID開發板的Android13系統下使用tinyplay播放wav格式的音頻

input keyevent 24 1|console:/sdcard # cat /proc/asound/cards console:/sdcard # ls -l /dev/snd/【需要打開Android13內置的音樂應用才會有聲音出來&#xff0c;原因未知&#xff01;】 1|console:/sdcard # tinyplay /sdcard/Music/kiss8.wav -D 1 -d 020250917在榮品RD-R…

總共分為幾種IP

IP&#xff08;Internet Protocol&#xff09;地址根據不同的分類標準可分為多種類型&#xff0c;以下是常見的分類方式&#xff1a;按版本分類IPv4&#xff1a;32位地址&#xff0c;格式為四組十進制數字&#xff08;如192.168.1.1&#xff09;&#xff0c;約43億個地址&#…

【Linux】常用命令(六)

【Linux】常用命令&#xff08;六&#xff09;1. yum命令1.1 基本語法1.2 常用命令2. 從服務器把數據cp到本地3. uname命令3.1 常用命令1. yum命令 全稱&#xff1a;Yellowdog Updater, Modified作用&#xff1a;是 RPM 包管理器的前端工具&#xff0c;用于基于 RPM 的 Linux …

go grpc開發使用

1、安裝proto 下載 Windows 版本 打開官方發布頁面 訪問 Protocol Buffers 的 GitHub Releases 頁面&#xff1a; &#x1f449; https://github.com/protocolbuffers/protobuf/releases 解壓 ZIP 文件 將下載的 ZIP 文件解壓到一個你容易找到的目錄&#xff0c;例如&#xff1…

MyBatis分頁:PageHelper

MyBatis分頁&#xff1a;PageHelper &#x1f4d6; 前言&#xff1a;為什么需要分頁&#xff1f; 在處理大量數據時&#xff0c;一次性從數據庫查詢并返回所有結果是不可行的&#xff0c;這會帶來巨大的性能和內存開銷。分頁是解決這一問題的標準方案。而PageHelper是一個極其流…