Skip to content
View thinkgin's full-sized avatar

Block or report thinkgin

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
thinkgin/README.md

ThinkGin

基于 Gin 的 Go Web 应用框架,提供开箱即用的工程化基础设施。

Go Gin License


特性

  • 模块化配置 — 13 个独立 YAML 文件,按职责隔离;THINKGIN_* 前缀环境变量覆盖
  • 多数据源 — GORM 接入 MySQL/PostgreSQL/SQLite(SQLite 纯 Go,无 cgo)
  • Redis 缓存go-redis/v9 多实例管理,启动期 Ping 探活
  • 结构化日志 — Logrus + 按天文件轮转,JSON/Text 格式可选
  • Prometheus 监控 — HTTP 四维 + 运行时 + 业务自定义指标,配置化启停
  • 链路追踪 — OpenTelemetry TracerProvider;GORM 插件把 SQL 纳入同一条 trace
  • 优雅停机 — 信号监听 + 超时 + DB/Cache/Tracer 依序释放,适配 Kubernetes
  • K8s 探针/livez 仅验证进程存活;/readyz 真实探测 DB/Redis,依赖降级时返 503
  • 可插拔中间件 — Recovery、RequestID、AccessLog、CORS、RateLimit、Trace、Prometheus、Session
  • Session 运行时memory / redis 两种 Store,Cookie 安全标志自动透传(HttpOnly/Secure/SameSite)
  • JWT 鉴权 — HS256 签发/校验,严格拒绝 alg=none 伪造;JWTFromContext 取 Claims

项目结构

thinkgin/
├── main.go                       # 入口:Bootstrap → DB/Cache/Tracer → Run
├── framework/                    # App 生命周期
│   ├── app.go
│   ├── options.go
│   └── browser.go
├── app/
│   ├── bootstrap.go              # Bootstrap(configDir) 显式入口
│   ├── loader.go                 # 13 个 YAML 的泛型加载器
│   ├── env.go                    # THINKGIN_* 环境变量覆盖
│   ├── defaults.go               # 零值默认填充
│   ├── validate.go               # 语义校验与纠偏
│   ├── config.go / types.go      # 全局 Config 单例 + 强类型
│   ├── logger.go                 # Logrus 初始化 + 跨平台文件轮转
│   ├── database/                 # GORM 多数据源 + OTel 插件
│   ├── cache/                    # Redis 多实例管理
│   └── index/                    # 示例业务模块 (MVC)
│       ├── controller/
│       ├── model/                # 含 User 示例
│       └── view/
├── config/                       # 13 个 YAML
├── route/                        # 路由按 web / api 拆分
├── extend/middleware/
│   ├── api_response.go           # 统一响应 + Recovery
│   ├── logger.go                 # RequestID + AccessLog
│   ├── cors.go / ratelimit.go
│   ├── trace.go                  # OTel TracerProvider 装配
│   └── prometheus*.go            # 指标按 http/system/business/handler 拆分
├── .github/workflows/ci.yml      # 三平台矩阵 + race + coverage
├── .golangci.yml                 # 精挑 linter
├── public/                       # 静态资源
└── runtime/                      # 运行时产物(日志)

快速开始

环境要求

  • Go 1.25+(Gin 1.12 通过 quic-go 间接要求 Go 1.25)
  • Git

安装与运行

# 克隆
git clone https://gitee.com/libaicode/thinkgin.git
cd thinkgin

# 配置 Go 代理(国内用户)
go env -w GOPROXY=https://goproxy.cn,direct

# 下载依赖
go mod tidy

# 运行
go run main.go

启动后访问:

地址 说明
http://localhost:8000 首页
http://localhost:8000/index/hello Hello World API
http://localhost:8000/metrics Prometheus 指标
http://localhost:8000/livez 存活探针

编译

# 本平台
go build -o thinkgin main.go

# 交叉编译
GOOS=linux GOARCH=amd64 go build -o thinkgin-linux main.go
GOOS=darwin GOARCH=arm64 go build -o thinkgin-darwin main.go

配置

所有配置位于 config/ 目录,每个文件独立管理一个模块:

文件 说明
app.yaml 应用名、版本、JWT、分页
server.yaml 监听地址、端口、超时、运行模式
database.yaml MySQL/PostgreSQL/SQLite 连接
cache.yaml Redis/内存缓存
log.yaml 日志级别、格式、轮转策略
middleware.yaml 全局中间件启用列表
prometheus.yaml 监控指标、认证、采集间隔
trace.yaml 链路追踪开关、采样率、导出方式
session.yaml 会话存储(memory / redis 已可用)
view.yaml 模板引擎
filesystem.yaml 文件存储(本地/OSS)
lang.yaml 国际化
route.yaml 路由配置

环境变量覆盖

所有核心配置支持 THINKGIN_ 前缀的环境变量覆盖:

THINKGIN_SERVER_MODE=release
THINKGIN_SERVER_HTTP_PORT=9090
THINKGIN_APP_DEBUG=false
THINKGIN_LOG_LEVEL=warn

中间件

通过 config/middleware.yaml 配置启用:

middleware:
  global:
    - recovery
    - request_id
    - trace
    - logger
    - prometheus
    - cors
    - rate_limit

业务监控示例

// 计数器
if c := middleware.BusinessCounter("api_calls", []string{"endpoint"}); c != nil {
    c.WithLabelValues("/api/users").Inc()
}

// 直方图
if h := middleware.BusinessHistogram("api_duration", []string{"endpoint"}, nil); h != nil {
    h.WithLabelValues("/api/users").Observe(elapsed.Seconds())
}

数据库与缓存

import (
    "thinkgin/app/cache"
    "thinkgin/app/database"
)

// 默认连接(对应 database.yaml 的 default 字段)
db := database.Default()

// 或按名取
pg, _ := database.Get("pgsql")

// Redis
rdb := cache.Default()

GORM 插件会自动为每条 SQL 开启 span,并以当前 HTTP 请求的 trace 为父节点—— 前提是业务代码用 db.WithContext(c.Request.Context()) 传递 context:

func ListUsers(c *gin.Context) {
    var users []model.User
    database.Default().WithContext(c.Request.Context()).Find(&users)
    c.JSON(200, users)
}

Session

config/middleware.yamlglobal 列表里加上 session,框架即自动挂载:

middleware:
  global:
    - recovery
    - request_id
    - session

业务代码:

import "thinkgin/app/session"

func Profile(c *gin.Context) {
    s := session.From(c)
    s.Set("user_id", 42)
    if err := s.Save(c.Request.Context()); err != nil {
        c.AbortWithError(500, err)
        return
    }
    c.JSON(200, gin.H{"ok": true})
}

func Logout(c *gin.Context) {
    _ = session.From(c).Destroy(c.Request.Context())
    session.ClearCookie(c)
    c.JSON(200, gin.H{"ok": true})
}

Store 切换仅需改 config/session.yaml

driver 状态 适用场景
memory 可用 单实例 / 开发调试
redis 可用 多副本部署,引用 database.yaml 中的 redis 连接
file / database 未实现

JWT 鉴权

密钥配置在 config/app.yamlapp.jwt.secret;过期时间 app.jwt.expire(秒)。

import "thinkgin/extend/middleware"

// 签发(ttl=0 时使用 app.jwt.expire;仍为 0 时兜底 2 小时)
token, err := middleware.JWTIssue("42", map[string]any{"role": "admin"}, 0)

// 保护路由:middleware.yaml 的 global 里加 "jwt",或按 group 注入
api := r.Group("/api/v1", middleware.JWTAuth())
api.GET("/me", func(c *gin.Context) {
    claims := middleware.JWTFromContext(c)
    c.JSON(200, gin.H{"uid": claims.Subject})
})

签名算法固定 HS256,解析时严格拒绝非 HMAC 算法,避免 alg=none 之类经典漏洞。

脚手架 CLI

生成新的业务模块骨架(MVC 三件套):

go run ./cmd/scaffold new module user
# app/user/controller/user.go
# app/user/model/user.go
# app/user/view/.gitkeep

命名规则:模块名必须以小写字母开头,只允许 a-z / 0-9 / _

测试 & CI

go test ./...
# 启用竞态检测(需要 cgo)
CGO_ENABLED=1 go test -race ./...

仓库根目录的 .github/workflows/ci.yml 会在 push / PR 时跑:

  • Build & Test:Ubuntu / Windows / macOS 三矩阵,启用 -race + coverage
  • Lintgolangci-lint,规则集见 .golangci.yml

部署

Docker

FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod tidy && go build -o thinkgin

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /app/thinkgin .
COPY --from=builder /app/config ./config
EXPOSE 8000
CMD ["./thinkgin"]
docker build -t thinkgin:3.0 .
docker run -p 8000:8000 thinkgin:3.0

Kubernetes

框架内置 /livez/readyz 探针,可直接配置:

livenessProbe:
  httpGet:
    path: /livez
    port: 8000
readinessProbe:
  httpGet:
    path: /readyz
    port: 8000

依赖

用途
gin-gonic/gin v1.12 HTTP 路由
sirupsen/logrus v1.9 结构化日志
prometheus/client_golang v1.20 监控指标
go.opentelemetry.io/otel v1.28 链路追踪
gorm.io/gorm v1.31 ORM
redis/go-redis/v9 v9.18 Redis 客户端
glebarez/sqlite SQLite 纯 Go 驱动
lestrrat-go/file-rotatelogs 日志轮转
gopkg.in/yaml.v3 YAML 解析

从 ThinkPHP 迁移?

如果你之前用 ThinkPHP,建议阅读 docs/migration-from-thinkphp.md, 里面列出了最常见的 20+ 对照项(Model、Route、Middleware、Config、View 等)。

数据库迁移

框架不内置迁移工具,推荐使用 pressly/goose。 用法与目录约定见 docs/database-migration.md

FAQ / 设计决策

一些反复被问到的问题和背后的取舍,集中写在 docs/faq.md

  • 为什么没有再封装一层"类 ThinkPHP 的 Model 链式调用"?
  • 为什么 Redis 的连接定义放在 database.yaml,而不是 cache.yaml
  • 为什么默认配置不预置 MySQL / Redis 连接?
  • 为什么 view.yaml / filesystem.yaml / lang.yaml 里几乎是空的?
  • 为什么 init() 里还保留了自动加载配置?

致谢

感谢 Gin 提供高性能的路由引擎。

许可证

MIT

Popular repositories Loading

  1. thinkgin thinkgin Public

    ThinkGin - 基于 Gin 的高性能 Go Web 框架,采用 ThinkPHP 式目录结构,内置配置、日志、链路追踪、Prometheus 监控与优雅停机。

    Go 26 4