
一个轻量级、实用的 Go 语言工具集,专注于提升开发效率与项目可维护性。
go-tools 是一套为 Go 开发者打造的通用工具函数集合,涵盖日志封装、IOC 服务注册、Kubernetes 操作辅助、HTTP 中间件、配置解析、字符串处理、加密安全、异常管理等核心功能。
所有组件均配有单元测试,确保稳定性与可靠性。
✅ 特性
- 🔧 模块化设计:各功能独立成包,按需引入。
- 🔐 安全加密:提供AES-GCM/AES-CBC加密、密钥管理、便捷加密函数 |
- 🚨 异常管理:统一的异常处理机制,支持错误链、序列化、自定义业务异常。
- 🧪 完整测试覆盖:核心功能均有
_test.go 测试文件验证。
- 🚀 生产就绪:已在多个内部服务中稳定运行。
- ☸️ K8s 的工具包:内置
k8sutil 包简化 ConfigMap/Deployment 管理。
- 🔄 依赖注入支持:通过
ioc 实现简易 IOC 容器管理对象生命周期。
- 📦 开箱即用:无需复杂配置,快速集成到现有项目中。
- ⏱️ 限速控制:提供令牌桶算法、滑动窗口、固定窗口等多种限速算法,支持API限流和资源保护。
📦 功能模块概览
| 包路径 |
功能说明 |
common |
常量、通用类型定义等共享资源 |
crypto |
加密安全模块:AES-GCM/AES-CBC加密、密钥管理、便捷加密函数 |
crypto/hash |
哈希算法:MD5、SHA256、SHA512、HMAC等 |
crypto/password |
密码安全:bcrypt、argon2密码哈希与验证 |
crypto/rand |
安全随机数:随机字符串、密码、UUID、令牌生成 |
crypto/sign |
数字签名:HMAC、RSA-PSS签名与验证 |
exception |
异常管理:统一异常处理、错误链、序列化、自定义业务异常 |
format |
字符串格式化工具(如 IndexOf 查找)、格式化打印对象 |
http/gin/middleware |
Gin 框架中间件(如拦截放通控制) |
ioc |
轻量级依赖注入容器,支持自动注册与查找,可注册app、grpc、api、conf等 |
k8s/k8sutil |
Kubernetes 客户端封装,支持 资源的 操作 |
logger |
日志初始化与 Zap 日志封装 |
ping |
心跳检测工具 |
rate |
限速控制:令牌桶算法、滑动窗口、固定窗口、漏桶算法,支持API限流和资源保护 |
resolver |
配置解析器,支持多源配置加载 |
scan |
结构体字段扫描与映射工具 |
tool_files |
存了一些比较常用的文件,例如比较模板化的makefile、Dockerfile等 |
⏱️ 限速控制模块
rate 包提供了多种限速算法,支持API限流和资源保护,确保系统在高并发场景下的稳定性。
支持算法
- 令牌桶算法:平滑的速率控制,支持突发流量,适合API限流场景
- 滑动窗口限速器:平滑控制请求频率,避免固定窗口的临界问题
- 固定窗口限速器:简单高效的固定时间窗口限速
- 漏桶算法:稳定的速率控制,适合流量整形
主要特性
- 线程安全设计,支持并发访问
- 灵活的配置选项,支持自定义时间窗口和突发容量
- 轻量级实现,低内存占用
- 完整的单元测试覆盖
- 支持多种Web框架(Gin、Go-Restful等)
📖 详细使用说明请参考 rate包文档
🔐 加密安全模块
1. AES-GCM 对称加密(简化版)
推荐使用方式:直接使用encrypt包
import "gitee.com/hexug/go-tools/crypto/encrypt"
// 生成密钥
key, err := encrypt.GenerateKey(32)
if err != nil {
panic(err)
}
// 直接加密解密(最简洁的方式)
plaintext := "敏感数据"
ciphertext, err := encrypt.EncryptString(key, plaintext)
if err != nil {
panic(err)
}
fmt.Println("加密结果:", ciphertext)
decrypted, err := encrypt.DecryptString(key, ciphertext)
if err != nil {
panic(err)
}
fmt.Println("解密结果:", decrypted)
使用Manager(适合固定密钥场景)
import "gitee.com/hexug/go-tools/crypto"
// 创建管理器(适合需要固定密钥的场景)
key, err := crypto.GenerateKey(32)
if err != nil {
panic(err)
}
mgr, err := crypto.NewManager(key)
if err != nil {
panic(err)
}
// 加密解密
ciphertext, err := mgr.EncryptString("敏感数据")
decrypted, err := mgr.DecryptString(ciphertext)
2. AES-CBC 对称加密
AES-CBC模式(兼容性更好,需要PKCS7填充)
import "gitee.com/hexug/go-tools/crypto/encrypt"
// 生成密钥
key, err := encrypt.GenerateKey(32)
if err != nil {
panic(err)
}
// 使用AES-CBC加密解密
plaintext := "需要加密的数据"
ciphertext, err := encrypt.EncryptStringCBC(key, plaintext)
if err != nil {
panic(err)
}
fmt.Println("AES-CBC加密结果:", ciphertext)
decrypted, err := encrypt.DecryptStringCBC(key, ciphertext)
if err != nil {
panic(err)
}
fmt.Println("AES-CBC解密结果:", decrypted)
使用AESCBC对象(更细粒度的控制)
import "gitee.com/hexug/go-tools/crypto/encrypt"
key, err := encrypt.GenerateKey(32)
if err != nil {
panic(err)
}
// 创建AES-CBC加密器
cipher := encrypt.NewAESCBC(key)
// 加密字节数据
ciphertext, err := cipher.Encrypt([]byte("字节数据"))
if err != nil {
panic(err)
}
// 解密字节数据
decrypted, err := cipher.Decrypt(ciphertext)
if err != nil {
panic(err)
}
fmt.Println("解密结果:", string(decrypted))
使用Manager的AES-CBC功能
import "gitee.com/hexug/go-tools/crypto"
key, err := crypto.GenerateKey(32)
if err != nil {
panic(err)
}
mgr, err := crypto.NewManager(key)
if err != nil {
panic(err)
}
// 使用Manager的AES-CBC方法
ciphertext, err := mgr.EncryptStringCBC("敏感数据")
decrypted, err := mgr.DecryptStringCBC(ciphertext)
// 或者获取AESCBC对象进行更细粒度的操作
aescbc := mgr.NewAESCBC()
ciphertext, err = aescbc.Encrypt([]byte("字节数据"))
decrypted, err = aescbc.Decrypt(ciphertext)
3. 哈希算法
import "gitee.com/hexug/go-tools/crypto/hash"
// 基本哈希
md5Hash := hash.MD5("hello")
sha256Hash := hash.SHA256("hello")
sha512Hash := hash.SHA512("hello")
// 多字符串哈希(与连接后哈希结果一致)
combinedHash := hash.MD5("hello", "world", "test")
// HMAC签名
hmac := hash.HMACSHA256("secret-key", "data1", "data2")
valid := hash.VerifyHMACSHA256("secret-key", []string{"data1", "data2"}, hmac)
4. 密码安全
import "gitee.com/hexug/go-tools/crypto/password"
// 密码哈希
password := "my-secret-password"
hashed, err := password.HashBCrypt(password)
if err != nil {
panic(err)
}
// 密码验证
valid, err := password.VerifyBCrypt(password, hashed)
if err != nil {
panic(err)
}
// 检查是否需要重哈希(升级密码策略)
needsRehash := password.NeedsRehash(hashed)
5. 安全随机数
import "gitee.com/hexug/go-tools/crypto/rand"
// 随机字符串
randomStr, err := rand.RandString(32)
// 随机密码
password, err := rand.RandPassword(12, true, true, true, true)
// UUID生成
uuid, err := rand.RandUUID()
// 随机令牌
token, err := rand.RandToken()
6. 数字签名
import (
"crypto/rsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"gitee.com/hexug/go-tools/crypto/sign"
)
// HMAC签名
signature, err := sign.GenerateHMACSignature("secret-key", "data")
valid, err := sign.VerifyHMACSignature("secret-key", signature, "data")
// RSA-PSS签名(需要生成RSA密钥对)
privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
signature, err := sign.SignString(sign.AlgRSAPSS, privateKey, "data")
valid, err := sign.VerifyStringSignature(sign.AlgRSAPSS, &privateKey.PublicKey, "data", signature)
// ECDSA签名(需要生成ECDSA密钥对)
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
signature, err := sign.SignString(sign.AlgECDSA, privateKey, "data")
valid, err := sign.VerifyStringSignature(sign.AlgECDSA, &privateKey.PublicKey, "data", signature)
// Ed25519签名(需要生成Ed25519密钥对)
privateKey, publicKey, _ := sign.GenerateEd25519KeyPair()
signature, err := sign.SignString(sign.AlgEd25519, privateKey, "data")
valid, err := sign.VerifyStringSignature(sign.AlgEd25519, publicKey, "data", signature)
4. 数字签名算法
支持多种签名算法:HMAC、RSA-PSS、ECDSA、Ed25519
import "gitee.com/hexug/go-tools/crypto/sign"
// HMAC签名示例
key := []byte("secret-key")
signature, err := sign.SignString(sign.AlgHMAC, key, "data to sign")
if err != nil {
panic(err)
}
valid, err := sign.VerifyStringSignature(sign.AlgHMAC, key, "data to sign", signature)
if err != nil {
panic(err)
}
fmt.Println("HMAC签名验证:", valid)
// RSA-PSS签名示例(需要RSA密钥对)
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
signature, err = sign.SignString(sign.AlgRSAPSS, privateKey, "data to sign")
if err != nil {
panic(err)
}
valid, err = sign.VerifyStringSignature(sign.AlgRSAPSS, &privateKey.PublicKey, "data to sign", signature)
if err != nil {
panic(err)
}
fmt.Println("RSA-PSS签名验证:", valid)
// ECDSA签名示例
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
signature, err = sign.SignString(sign.AlgECDSA, privateKey, "data to sign")
if err != nil {
panic(err)
}
valid, err = sign.VerifyStringSignature(sign.AlgECDSA, &privateKey.PublicKey, "data to sign", signature)
if err != nil {
panic(err)
}
fmt.Println("ECDSA签名验证:", valid)
// Ed25519签名示例
privateKey, publicKey, err := sign.GenerateEd25519KeyPair()
if err != nil {
panic(err)
}
signature, err = sign.SignString(sign.AlgEd25519, privateKey, "data to sign")
if err != nil {
panic(err)
}
valid, err = sign.VerifyStringSignature(sign.AlgEd25519, publicKey, "data to sign", signature)
if err != nil {
panic(err)
}
fmt.Println("Ed25519签名验证:", valid)
便捷函数示例
// HMAC便捷函数
signature, err := sign.GenerateHMACSignature("secret-key", "data1", "data2", "data3")
if err != nil {
panic(err)
}
valid, err := sign.VerifyHMACSignature("secret-key", signature, "data1", "data2", "data3")
if err != nil {
panic(err)
}
// ECDSA便捷函数
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
signature, err := sign.GenerateECDSASignature(privateKey, "data1", "data2")
if err != nil {
panic(err)
}
valid, err := sign.VerifyECDSASignature(&privateKey.PublicKey, signature, "data1", "data2")
if err != nil {
panic(err)
}
// Ed25519便捷函数
privateKey, publicKey, _ := sign.GenerateEd25519KeyPair()
signature, err := sign.GenerateEd25519Signature(privateKey, "data1", "data2")
if err != nil {
panic(err)
}
valid, err := sign.VerifyEd25519Signature(publicKey, signature, "data1", "data2")
if err != nil {
panic(err)
}
🚨 异常管理模块
1. 基础异常使用
import "gitee.com/hexug/go-tools/exception"
// 创建标准异常
notFoundErr := exception.NewNotFound("用户 %s 不存在", "alice")
badRequestErr := exception.NewBadRequest("请求参数错误")
internalErr := exception.NewInternalServerError("服务器内部错误")
// 添加额外信息
err := exception.NewApiException(1001, "业务错误").
WithMessage("具体错误描述").
WithNamespace("user-service").
WithMeta("user_id", "123").
WithData(map[string]any{"retry_count": 3})
2. 错误链支持
import "errors"
// 包装底层错误
rootErr := errors.New("数据库连接失败")
apiErr := exception.NewApiExceptionWithCause(
exception.CODE_INTERNAL_SERVER_ERROR,
"用户数据获取失败",
rootErr,
)
// 检查错误链
if errors.Is(apiErr, rootErr) {
fmt.Println("包含底层错误")
}
3. 序列化与反序列化
// 序列化为JSON
jsonStr := apiErr.ToJson()
// 从JSON反序列化
parsedErr := exception.NewApiExceptionFromString(jsonStr)
4. 自定义业务异常
const (
CodeUserLocked = 60001
)
// 定义业务异常
func NewUserLocked(user string) *exception.ApiException {
return exception.NewApiException(CodeUserLocked, "用户被锁定").
WithMessagef("用户 %s 已被锁定", user).
WithNamespace("user-service").
WithMeta("user", user).
WithHttpCode(http.StatusForbidden)
}
// 使用业务异常
func CheckUserStatus(userID string) error {
if isLocked(userID) {
return NewUserLocked(userID)
}
return nil
}
5. 异常类型判断
// 使用辅助函数判断异常类型
if exception.IsNotFoundError(err) {
// 处理未找到错误
} else if exception.IsConflictError(err) {
// 处理冲突错误
}
// 自定义异常判断
func IsUserLocked(err error) bool {
return exception.IsApiException(err, CodeUserLocked)
}
🚀 快速开始
1. 安装
go get gitee.com/hexug/go-tools
⚠️ 注意:请确保你的 GOPROXY 设置正确以加速拉取(推荐 GOPROXY=https://goproxy.cn,direct)
2. 使用示例
🔹 加密安全示例(推荐方式)
package main
import (
"fmt"
"gitee.com/hexug/go-tools/crypto/encrypt"
"gitee.com/hexug/go-tools/crypto/password"
)
func main() {
// AES-GCM加密示例(最简洁的方式)
key, _ := encrypt.GenerateKey(32)
ciphertext, _ := encrypt.EncryptString(key, "敏感数据")
decrypted, _ := encrypt.DecryptString(key, ciphertext)
fmt.Println("AES-GCM加密解密成功:", decrypted)
// AES-CBC加密示例(兼容性更好)
ciphertextCBC, _ := encrypt.EncryptStringCBC(key, "敏感数据")
decryptedCBC, _ := encrypt.DecryptStringCBC(key, ciphertextCBC)
fmt.Println("AES-CBC加密解密成功:", decryptedCBC)
// 密码哈希示例
hashed, _ := password.HashBCrypt("my-password")
valid, _ := password.VerifyBCrypt("my-password", hashed)
fmt.Println("密码验证:", valid)
}
🔹 异常管理示例
package main
import (
"fmt"
"gitee.com/hexug/go-tools/exception"
)
func getUser(userID string) error {
if userID == "" {
return exception.NewBadRequest("用户ID不能为空")
}
// 模拟用户不存在
return exception.NewNotFound("用户 %s 不存在", userID)
}
func main() {
err := getUser("")
if err != nil {
if exception.IsBadRequestError(err) {
fmt.Println("请求参数错误:", err.Error())
} else if exception.IsNotFoundError(err) {
fmt.Println("用户不存在:", err.Error())
}
}
}
🔹 IOC 容器注册与获取 (ioc)
import "gitee.com/hexug/go-tools/ioc"
// TODO 查看测试用例
🔹 K8s 操作 (k8s)
需要提前在k8s目录下存放一个kubeconfig文件,并且命名为 conf.yml
否则有些测试用例可能会报错
import "gitee.com/hexug/go-tools/k8s"
🔹 Gin 中间件:请求拦截放通 (http/gin/middleware)
import (
"github.com/gin-gonic/gin"
"gitee.com/hexug/go-tools/http/gin/middleware"
)
// TODO 查看测试用例
import "gitee.com/hexug/go-tools/format"
// TODO 查看测试用例
🔹 限速控制示例 (rate)
import (
"context"
"fmt"
"gitee.com/hexug/go-tools/rate"
)
// 令牌桶算法示例(推荐用于API限流)
// 创建令牌桶限速管理器:每秒10个请求,突发容量20个
limiter := rate.NewTokenBucketManager(10, 20)
// 检查是否允许请求
if allowed, _ := limiter.CheckRateLimit(context.Background(), "/api/v1/users"); allowed {
fmt.Println("令牌桶:请求通过限速检查")
} else {
fmt.Println("令牌桶:请求被限速")
}
// 滑动窗口限速器示例
slidingLimiter := rate.NewSlidingWindowManager(10)
if allowed, _ := slidingLimiter.CheckRateLimit(context.Background(), "/api/v1/products"); allowed {
fmt.Println("滑动窗口:请求通过限速检查")
}
// 固定窗口限速器示例
fixedLimiter := rate.NewFixedWindowManager(100)
if allowed, _ := fixedLimiter.CheckRateLimit(context.Background(), "/api/v1/search"); allowed {
fmt.Println("固定窗口:请求通过限速检查")
}
// 漏桶算法示例
leakyLimiter := rate.NewLeakyBucketManager(5, 10)
if allowed, _ := leakyLimiter.CheckRateLimit(context.Background(), "/api/v1/upload"); allowed {
fmt.Println("漏桶算法:请求通过限速检查")
}
// 动态切换算法示例
func switchAlgorithm(algorithm rate.RateType) {
// 根据需求动态选择算法
config := rate.RateConfig{Rate: 50, Burst: 100}
switch algorithm {
case rate.TokenBucket:
limiter = rate.NewRateManagerWithAlgorithmConfig(config, rate.TokenBucket)
fmt.Println("切换到令牌桶算法")
case rate.SlidingWindow:
limiter = rate.NewRateManagerWithAlgorithmConfig(config)
fmt.Println("切换到滑动窗口算法")
case rate.FixedWindow:
limiter = rate.NewRateManagerWithAlgorithmConfig(config)
fmt.Println("切换到固定窗口算法")
case rate.LeakyBucket:
limiter = rate.NewRateManagerWithAlgorithmConfig(config, rate.LeakyBucket)
fmt.Println("切换到漏桶算法")
}
}
// 设置路由级限速示例
func setupRouteLimits() {
manager := rate.NewDefaultRateManager()
// 为不同路由设置不同的限速策略
manager.SetRouteLimit("/api/v1/login", rate.RateConfig{Rate: 5, Burst: 10})
manager.SetRouteLimit("/api/v1/upload", rate.RateConfig{Rate: 10, Burst: 20})
manager.SetRouteLimit("/api/v1/search", rate.RateConfig{Rate: 30, Burst: 60})
fmt.Println("路由级限速配置完成")
}
🧪 测试与验证
所有模块都包含完整的单元测试,可以通过以下命令运行测试:
# 运行所有测试
go test ./...
# 运行加密模块测试
go test ./crypto/...
# 运行异常管理模块测试
go test ./exception/...
# 运行基准测试
go test -bench=. ./crypto/...
测试用例提供了丰富的使用示例和最佳实践,建议查看对应的 *_test.go 文件。
🔧 最佳实践
加密安全
- 密钥管理:使用安全的方式存储和管理加密密钥
- 密码哈希:始终使用bcrypt或argon2进行密码哈希
- 随机数生成:使用密码学安全的随机数生成器
- 签名验证:对重要数据进行签名验证,防止篡改
异常管理
- 统一异常类型:使用预定义的异常类型保持一致性
- 错误链包装:包装底层错误,保持错误上下文
- 业务异常自定义:为特定业务场景定义专门的异常类型
- 异常序列化:在跨服务调用时使用JSON序列化传递异常
🧩 如何贡献
欢迎提交 Issue 或 Pull Request!
- Fork 本项目
- 创建特性分支:
git checkout -b feat/new-feature
- 提交更改:
git commit -m 'feat: add xxx'
- 推送到远程:
git push origin feat/new-feature
- 提交 PR
📌 提交前请确保:
- 所有测试通过:
go test ./...
- 代码格式化:
gofmt -s -w .
- 添加对应文档说明
📄 许可证
本项目未明确声明许可证,默认采用 Apache 2.0 License。使用时请自行评估风险,并遵守上游依赖的许可要求。
如需正式授权,请联系作者。
🙌 致谢
感谢 Gitee 提供稳定的代码托管平台。
Built with ❤️ by hexug
如果你觉得这个项目对你有帮助,不妨点个 Star ⭐ 支持一下!