分享我的开源项目:go-sail
go-sail 是什么?
go-sail 是一个轻量的渐进式 Web 框架,使用 Go 语言实现。它并不是重复造轮子的产物,而是站在巨人的肩膀上,整合现有的优秀组件,旨在帮助使用者以最简单的方式构建稳定可靠的服务。 正如它的名字一般,你可以把它视作自己在 Golang 生态的一个开始。go-sail 将助力你从轻出发,扬帆起航。
仓库地址
https://github.com/keepchen/go-sail/
如何使用
推荐 go version >= 1.23
复制
go get -u github.com/keepchen/go-sail/v3
复制
import ( "net/http" "github.com/gin-gonic/gin" "github.com/keepchen/go-sail/v3/sail" "github.com/keepchen/go-sail/v3/sail/config" ) var ( conf = &config.Config{} registerRoutes = func(ginEngine *gin.Engine) { ginEngine.GET("/hello", func(c *gin.Context){ c.String(http.StatusOK, "%s", "hello, world!") }) } ) func main() { sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch() }
示例
配置读取
复制
parseFn := func(content []byte, viaWatch bool){ fmt.Println("config content: ", string(content)) if viaWatch { //reload config... } } etcdConf := etcd.Conf{ Endpoints: []string{""}, Username: "", Password: "", } key := "go-sail.config.yaml" sail.Config(parseFn).ViaEtcd(etcdConf, key).Parse(parseFn)
链路日志追踪
复制
func UserRegisterSvc(c *gin.Context) { ... sail.LogTrace(c).Warn("log something...") ... }
JWT 认证
- 颁发令牌
复制
func UserLoginSvc(c *gin.Context) { ... uid := "user-1000" exp := time.Now().Add(time.Hour * 24).Unix() otherFields := map[string]interface{}{ "nickname": "go-sail", "avatar": "https://go-sail.dev/assets/avatar/1.png", ... } ok, token, err := sail.JWT().MakeToken(uid, exp, otherFields) ... }
- 认证
复制
func UserInfoSvc(c *gin.Context) { ... ok, claims, err := sail.JWT().ValidToken(token) ... }
组件
响应器
复制
func UserInfoSvc(c *gin.Context) { sail.Response(c).Wrap(constants.ErrNone, resp).Send() }
数据库
- 读写分离
复制
func UserInfoSvc(c *gin.Context) { uid := "user-1000" var user models.User //READ: query user info sail.GetDBR().Where("uid = ?", uid).First(&user) ... //WRITE: update user info sail.GetDBW().Model(&models.User{}). Where("uid = ?", uid). Updates(map[string]interface{}{ "avatar": "https://go-sail.dev/assets/avatar/2.png" }) }
- 事务
复制
func UserInfoSvc(c *gin.Context) { uid := "user-1000" err := sail.GetDBW().Transaction(func(tx *gorm.DB){ e1 := tx.Model(&models.User{}). Where("uid = ?", uid). Updates(map[string]interface{}{ "avatar": "https://go-sail.dev/assets/avatar/2.png" }).Error if e1 != nil { return e1 } e2 := tx.Create(&models.UserLoginHistory{ Uid: uid, ... }).Error return e2 }) }
Redis
复制
func UserInfoSvc(c *gin.Context) { ... sail.GetRedis().Set(ctx, "go-sail:userInfo", "user-1000", time.Hour*24).Result() ... }
计划任务
- 周期性的
复制
func TodoSomething() { fn := func() { ... } sail.Schedule("todoSomething", fn).Daily() }
- Linux Crontab 风格的
复制
func TodoSomething() { fn := func() { ... } sail.Schedule("todoSomething", fn).RunAt("*/5 * * * *") }
- 竞态检测
复制
func TodoSomething() { fn := func() { ... } sail.Schedule("todoSomething", fn).Withoutoverlapping().RunAt("*/5 * * * *") }
分布式锁
复制
func UpdateUserBalance() { if !sail.RedisLocker().TryLock(key) { return false } defer sail.RedisLocker().Unlock(key) ... }
文档
在线示例
功能特性
- HTTP 响应器
- 统一响应字段
- 管理 HTTP 状态码
- 管理业务码
- 组件库
- Database
- Jwt
- Kafka
- Logger
- Nacos
- Etcd
- Nats
- Redis
- Valkey
- 服务注册与发现
- Nacos
- Etcd
- 工具类
- 加解密
- 文件
- ip
- 字符串
- 随机数
- 日期时间
- ...
- 日志收集与导出
- 本地文件
- 导出器
- Redis
- Kafka
- Nats
- 计划任务
- 可取消的
- 一次性的
- 周期性的
- Linux Crontab 风格的
- 竞态检测
- 遥测与可观测性
- 调用链追踪
- Prometheus
- Pprof
- 日志导出器
- 性能监测
- Prometheus
- Pprof
- 接口错误码
- 动态注入
- 国际化
- 基于 Redis 的分布式锁
- 阻塞式
- 非阻塞式
- 接口文档
- Redocly
- Swagger
- 配置管理
- File
- Etcd
- Nacos
其他
- 欢迎大家提 PR: pull request
- 欢迎大家提出自己的想法: issue
- 感谢你的 star 如果你喜欢这个项目的话 :)
已点 star,go 这几年发展的真快