go-infra

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: MIT

README

go-infra

Go 基础设施工具集,用于构建生产级应用。

说明
lifecycle 应用生命周期管理:顺序启动、LIFO 关闭、信号处理、优雅停机
licensing 离线软件授权:Ed25519 签名、机器绑定、Feature/Capacity 两层授权、密钥轮换
cache LRU 缓存:支持容量限制、驱逐回调、线程安全包装
buffer/ring 环形缓冲区:实现 io.Reader/io.Writer,支持自动扩容、ReadFrom/WriteTo
buffer/ringpool 环形缓冲对象池:带自适应校准,减少 GC 压力
buffer/elastic 弹性环形缓冲区:懒加载池化缓冲,空时自动归还
queue 无锁队列:基于 CAS 的高性能队列,支持 MPSC/MPMC 场景
bytepool 字节切片池:32 级分级池,减少 GC 压力
mathutil 数学工具:2 的幂运算(Ceil/Floor/Closest/IsPowerOfTwo)
bytesconv 零拷贝转换:[]bytestring 无内存分配转换
randutil 随机字符串:支持 math/randcrypto/rand,DNS-1035 兼容
envutil 环境变量解析:String/Int/Float64/Bool,支持默认值和必填
strutil 字符串工具:SwapCase、Capitalize、Abbreviate、Reverse、Truncate 等
sliceutil 切片工具:Unique、Intersect、Map、Filter、Reduce(泛型实现)

使用

import "github.com/qoderwork/go-infra/lifecycle"

func main() {
    mgr := lifecycle.New(lifecycle.WithTimeout(10 * time.Second))
    mgr.Add(myDB)
    mgr.Add(myHTTPServer)
    mgr.Run() // 阻塞直到收到信号,然后优雅关闭
}

完整示例见 examples

设计原则

  • KISS — 最小 API 表面,没有不必要的抽象
  • 注册顺序即优先级 — 先加的先启动、后关闭,和 defer 一样直觉
  • 零隐藏 goroutine — Manager 不会在调用者 goroutine 之外偷偷起后台线程(唯一例外是 WaitSignal,由 Go runtime 的信号处理 goroutine 负责捕获 SIGINT/SIGTERM,与你的代码无关)。Task.Start / Task.Stop 由 Manager 在调用者 goroutine 同步驱动,但 Task 自己可以用 go 起后台服务——Start 不必阻塞,返回即代表"已启动"。
  • 幂等关闭sync.Once 保证 Stop 安全调用多次

停机触发源

Manager 提供两种"等停机信号"的入口,按需选择:

  • mgr.Run() —— 推荐入口Start 之后自动监听系统信号(SIGINT / SIGTERM,Windows 上为 Ctrl+C),收到后优雅关闭。适合独立二进制。
  • mgr.WaitSignal(timeout) —— 与 Run 内部逻辑相同,但你可以先 Start 再做别的事,再手动等待信号。
  • mgr.Wait(ctx) —— 停机由你自己的 context 驱动(如测试、K8s 探针、父进程编排),不依赖 OS 信号。把 ctx 取消即可触发优雅关闭。

授权(license 包)

极简、零依赖的离线软件授权方案。用 Ed25519 数字签名而非加密来保证防篡改与身份认证:授权文件是明文 JSON,可被审计;防伪造靠的是签名,不是隐藏内容。

核心概念
  • 签发 / 验签分离license-tool 持有私钥签发授权;你的程序只内置公钥验签,无法伪造。
  • 数据模型LicenseID / Product / Subject / Features[] / Capacity / NotBefore / Expiry / Machine / VersionFeatures 是功能开关列表,Capacity 是数量上限(map[string]int64),二者构成 Feature + Capacity 两层授权。
  • 确定性签名:签名字节 = License 结构体的 JSON 编码。Go 的 json 按字段声明顺序输出、并对 map 的 key 排序,因此签发端与验签端产生完全一致字节。
  • 机器绑定Machine 声明允许的机器指纹列表;strict(默认)要求精确匹配,指纹源缺失或读取失败即拒绝;loose 在指纹源缺失或读取失败时放行(best-effort),但成功读取后仍需匹配。指纹由 licensing/machine 计算(Linux: dmidecode system-uuid → 主板序列号 → /etc/machine-id;macOS: system_profiler;Windows: PowerShell),sha256 归一化为 UUID v5 格式,fail-closed 拒绝 hostname/MAC 等可变标识符与占位符
  • 密钥轮换Version 字段选择验签用的公钥;Verifier.WithKey(v, pub) 注册多版本公钥,换密钥时旧授权仍有效。
快速开始

签发(在你这边,持有私钥):

go run ./cmd/license-tool genkey -priv private.pem -pub public.pem
# 写一个 template.json(字段见 License 结构体),然后:
go run ./cmd/license-tool sign -key private.pem -in template.json -out license.lic

验签(在程序里,只内置公钥):

pub, _ := licensing.DecodePublicKeyPEM(pubPEM) // pubPEM 用 go:embed 内置
data, _ := os.ReadFile("license.lic")
v, _ := licensing.NewVerifier(pub, licensing.CurrentVersion)
lic, err := v.WithFingerprint(machine.Fingerprint).Verify(data)
if err != nil { /* 授权无效:err 说明原因 */ }
_ = lic.HasFeature("advanced")
n := lic.CapacityOf("nodes")

CLI 还有 verify(手动校验)和 fingerprint(打印当前机器指纹)两个子命令。完整演示见 examples/license

安全预期(重要)

离线授权是君子级防护,不是保险箱

  • ✅ 有效签名 = 授权确由私钥签发、且未被篡改;机器绑定防止 .lic 文件被拷贝到别机。
  • ⚠️ 不防二进制补丁:攻击者可 patch 程序跳过 Verify(),或改内存里的 Expiry。如需更强保护,请额外加二进制完整性校验 / 混淆。
  • ⚠️ 时间旅行:离线环境下改系统时间可绕过过期。可用 Verifier.WithMinClock() 接到一个持久化的"已知最晚时间"来防御时钟回拨。
  • 私钥泄露需走轮换流程(升 Version 并签发新密钥,旧版授权靠 WithKey 兼容)。

License

MIT

Directories

Path Synopsis
buffer
elastic
Package elastic implements an elastic ring-buffer that lazily acquires buffers from a pool and returns them when empty.
Package elastic implements an elastic ring-buffer that lazily acquires buffers from a pool and returns them when empty.
ring
Package ring implements a memory-efficient circular buffer that implements the io.Reader and io.Writer interfaces.
Package ring implements a memory-efficient circular buffer that implements the io.Reader and io.Writer interfaces.
ringpool
Package ringpool implements a GC-friendly pool of ring buffers.
Package ringpool implements a GC-friendly pool of ring buffers.
Package bytepool provides a pool of byte slices consisting of sync.Pool's that collect byte slices with different length sizes in powers of two.
Package bytepool provides a pool of byte slices consisting of sync.Pool's that collect byte slices with different length sizes in powers of two.
Package bytesconv provides zero-copy conversion utilities between byte slices and strings.
Package bytesconv provides zero-copy conversion utilities between byte slices and strings.
Package cache provides caching implementations.
Package cache provides caching implementations.
cmd
license-tool command
Command license-tool issues and verifies offline software licenses.
Command license-tool issues and verifies offline software licenses.
Package envutil provides environment variable parsing utilities.
Package envutil provides environment variable parsing utilities.
Package licensing — crypto.go
Package licensing — crypto.go
machine
Package machine computes a stable, normalized machine fingerprint used to bind a license to a physical (or virtual) machine.
Package machine computes a stable, normalized machine fingerprint used to bind a license to a physical (or virtual) machine.
Package lifecycle provides a minimal application lifecycle manager.
Package lifecycle provides a minimal application lifecycle manager.
Package mathutil provides fast math utility functions.
Package mathutil provides fast math utility functions.
Package queue provides queue implementations.
Package queue provides queue implementations.
Package randutil provides random string generation utilities.
Package randutil provides random string generation utilities.
Package sliceutil provides slice manipulation utilities.
Package sliceutil provides slice manipulation utilities.
Package strutil provides string manipulation utilities.
Package strutil provides string manipulation utilities.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL