Skip to content

attains/go-skeleton

Repository files navigation

go-skeleton

Go 应用骨架 SDK,可作为项目的 core 模块快速搭建服务。

功能

模块 说明
config 基于 viper,支持本地文件 / etcd / consul 远程配置,支持配置热更新,支持 a.b.c 格式获取自定义配置
logger 基于 zap + lumberjack,支持 JSON / console 格式,日志轮转
database 基于 gorm,支持 MySQL / PostgreSQL / SQLite,多实例按名称获取,可配置日志级别
redis 基于 go-redis/v9,多实例按名称获取
lock 基于 Redis 的分布式锁,支持重试、续期,使用 crypto/rand 保证唯一性
elasticsearch 基于 go-elasticsearch/v8,多实例按名称获取
meilisearch 基于 meilisearch-go,多实例按名称获取
kafka 基于 segmentio/kafka-go,支持生产 / 消费
rabbitmq 基于 amqp091-go,支持发布 / 消费 / 声明队列和交换机
storage/oss 阿里云 OSS 存储
storage/cos 腾讯云 COS 存储
cron 基于 robfig/cron/v3,支持秒级精度
idgen 基于 yitter/idgenerator-go,支持本地 / Redis 分布式 ID 生成
server/http 基于 gin,内置 zap 日志和 panic recovery 中间件
server/grpc 基于 grpc-go,内置日志和 recovery 拦截器(使用原生 ChainInterceptor)
response 统一 HTTP / gRPC 响应格式
middleware CORS、RequestID、JWT 认证中间件

安装

go get github.com/attains/go-skeleton

快速开始

  1. 复制 config.example.yamlconfig.yaml 并修改配置。

  2. 编写代码:

package main

import (
    "log"

    sk "github.com/attains/go-skeleton"
    "github.com/attains/go-skeleton/config"
    "github.com/attains/go-skeleton/middleware"
    "github.com/attains/go-skeleton/response"
    "github.com/gin-gonic/gin"
)

func main() {
    app, err := sk.New(
        sk.WithConfig(config.WithFile("config.yaml")),
        sk.WithDB(),
        sk.WithRedis(),
        sk.WithHTTP(),
        sk.WithGRPC(),
        sk.WithCron(),
        sk.WithIDGen(),
    )
    if err != nil {
        log.Fatal(err)
    }

    // 注册中间件
    app.HTTPServer.Engine().Use(middleware.CORS())
    app.HTTPServer.Engine().Use(middleware.RequestID())

    // 注册 HTTP 路由
    app.HTTPServer.Engine().GET("/ping", func(c *gin.Context) {
        response.OK(c, gin.H{"message": "pong"})
    })

    // 需要认证的路由
    auth := app.HTTPServer.Engine().Group("/api", middleware.JWTAuth([]byte("your-secret")))
    auth.GET("/profile", func(c *gin.Context) {
        userID := middleware.GetUserID(c)
        response.OK(c, gin.H{"user_id": userID})
    })

    // 注册 gRPC 服务
    // pb.RegisterXxxServer(app.GRPCServer.Server(), &service{})

    // 添加定时任务
    app.Cron.AddFunc("0 */5 * * * *", func() {
        // 每5分钟执行
    })

    // 启动服务(同时启动 HTTP + gRPC + Cron,阻塞等待退出信号)
    if err := app.Run(); err != nil {
        log.Fatal(err)
    }
}

按需启用模块

通过 With*() 选项按需启用模块,未启用的模块不会初始化连接:

// 只启用 HTTP + 数据库
app, _ := sk.New(
    sk.WithConfig(config.WithFile("config.yaml")),
    sk.WithDB(),
    sk.WithHTTP(),
)

// 启用全部模块
app, _ := sk.New(
    sk.WithConfig(config.WithFile("config.yaml")),
    sk.WithAll(),
)

多实例获取

数据库、Redis、Elasticsearch、Meilisearch 均支持多实例,通过名称获取:

// 获取默认实例(name=default)
db, err := app.DB.Get()
rdb, err := app.Redis.Get()

// 获取指定名称实例
db, err := app.DB.Get("secondary")
rdb, err := app.Redis.Get("cache")

// panic 版本(适合初始化阶段)
db := app.DB.MustGet()

分布式锁

import "github.com/attains/go-skeleton/lock"

// 使用默认 Redis 实例获取锁
l, err := app.AcquireLock(ctx, "order:123",
    lock.WithTTL(10*time.Second),
    lock.WithRetry(3, 200*time.Millisecond),
)
if err != nil {
    // 获取锁失败
}
defer l.Release(ctx)

// 指定 Redis 实例
l, err := app.AcquireLockOn(ctx, "cache", "order:123")

分布式 ID

import "github.com/attains/go-skeleton/idgen"

id := idgen.NextID()

统一响应

import "github.com/attains/go-skeleton/response"

// HTTP 响应
response.OK(c, data)                             // {"code":0,"message":"ok","data":...}
response.OKWithPage(c, list, total, page, size)   // 分页响应
response.Fail(c, 10001, "业务错误")                // {"code":10001,"message":"业务错误"}
response.BadRequest(c, "参数错误")
response.Unauthorized(c, "未登录")
response.ServerError(c, "内部错误")

// gRPC 错误
return nil, response.GRPCInvalidArgument("参数错误")
return nil, response.GRPCNotFound("资源不存在")

中间件

import "github.com/attains/go-skeleton/middleware"

// CORS
engine.Use(middleware.CORS())
engine.Use(middleware.CORS(middleware.CORSConfig{
    AllowOrigins: []string{"https://example.com"},
}))

// RequestID — 自动生成或透传 X-Request-ID
engine.Use(middleware.RequestID())

// JWT 认证
engine.Use(middleware.JWTAuth([]byte("signing-key")))

// 生成 Token
token, _ := middleware.GenerateToken(middleware.JWTConfig{
    SigningKey: []byte("signing-key"),
    Issuer:    "my-app",
    ExpireIn:  24 * time.Hour,
}, userID, username)

// 在 handler 中获取用户信息
userID := middleware.GetUserID(c)
username := middleware.GetUsername(c)

配置热更新

app, _ := sk.New(
    sk.WithConfig(
        config.WithFile("config.yaml"),
        config.WithWatch(func() {
            // 配置变更回调
            log.Println("config changed")
        }),
    ),
)

远程配置(etcd / consul)

app, _ := sk.New(
    sk.WithConfig(
        config.WithRemote("etcd3", "http://127.0.0.1:2379", "/config/myapp", "yaml"),
        config.WithWatch(nil),
    ),
)

自定义配置

配置文件中未在结构体中定义的字段,可通过 a.b.c 格式获取:

val := app.Config.GetString("custom.feature_flag")
num := app.Config.GetInt("custom.max_retry")
ok  := app.Config.GetBool("custom.enabled")

项目结构

go-skeleton/
├── skeleton.go          # 核心 App 引导,组装所有模块
├── config/              # 配置解析(viper)
├── logger/              # 日志(zap)
├── database/            # 数据库(gorm)
├── redis/               # Redis
├── lock/                # 分布式锁
├── elasticsearch/       # Elasticsearch
├── meilisearch/         # Meilisearch
├── kafka/               # Kafka
├── rabbitmq/            # RabbitMQ
├── storage/
│   ├── oss/             # 阿里云 OSS
│   └── cos/             # 腾讯云 COS
├── cron/                # 定时任务
├── idgen/               # 分布式 ID 生成
├── response/            # 统一响应格式
├── middleware/           # HTTP 中间件(CORS / RequestID / JWT)
└── server/
    ├── http/            # HTTP 服务(gin)
    └── grpc/            # gRPC 服务

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors