Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

keepchen/go-sail

Open more actions menu

Repository files navigation

sailboat-solid

Go CodeQL Go Report Card codecov Dependabot Status Snyk Security LICENSE: MIT

LATEST_VERSION

简体中文 | English

go-sail是什么?

go-sail是一个轻量的渐进式Web框架,使用Go语言实现。它并不是重复造轮子的产物,而是站在巨人的肩膀上,整合现有的优秀组件,旨在帮助使用者以最简单的方式构建稳定可靠的服务。 正如它的名字一般,你可以把它视作自己在golang生态的一个开始。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()
}

当你看到终端如下图所示内容就表示服务启动成功了:

launch.png

示例

配置读取

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(true, 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

其他插件

README.md

基准测试

ulimit -n 65535 && sh run_benchmark.sh

测试结果(真实的HTTP请求)

goos: darwin
goarch: amd64
pkg: github.com/keepchen/go-sail/v3
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkGoSailParallel-12    88252    12898 ns/op    8860 B/op    92 allocs/op
BenchmarkGinParallel-12       96548    11722 ns/op    7187 B/op    82 allocs/op
PASS
ok    github.com/keepchen/go-sail/v3  3.663s

benchmark-result.png

大感谢

感谢在体验、使用过程中提出宝贵建议和意见以及提供过其他各种帮助的各位小伙伴!

其他

  • 欢迎大家提PR: pull request
  • 欢迎大家提出自己的想法: issue
  • 感谢你的star如果你喜欢这个项目的话 :)

使用案例

stardots.io Piggy (telegram mini-game) 生活好评助手-小程序
WinGoal Pikaster FantaGoal

赞助

Powered by DartNode

Star历史

Star History Chart

Morty Proxy This is a proxified and sanitized view of the page, visit original site.