分享我的开源项目:go-sail

4 条回复
61 次浏览

go-sail 是什么?

go-sail 是一个轻量的渐进式 Web 框架,使用 Go 语言实现。它并不是重复造轮子的产物,而是站在巨人的肩膀上,整合现有的优秀组件,旨在帮助使用者以最简单的方式构建稳定可靠的服务。 正如它的名字一般,你可以把它视作自己在 Golang 生态的一个开始。go-sail 将助力你从轻出发,扬帆起航。

仓库地址

https://github.com/keepchen/go-sail/

LATEST_VERSION

如何使用

推荐 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)
  ...
}

文档

https://go-sail.dev

在线示例

https://nav.go-sail.dev

功能特性

  • HTTP 响应器
    • 统一响应字段
    • 管理 HTTP 状态码
    • 管理业务码
  • 组件库
    • Database
    • Email
    • 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 如果你喜欢这个项目的话 :)
马上来

一股子 java 味道,和垃圾 goframe 有啥不一样,全是站在巨人肩膀上乱拉屎。

发表一个评论

R保持