调整工具类的方法,优化方法调用及增加迁移工具及其用法

This commit is contained in:
2025-12-04 22:30:48 +08:00
parent de8fc13f18
commit 0650feb0d2
28 changed files with 3753 additions and 162 deletions

406
README.md
View File

@@ -2,11 +2,44 @@
这是一个Go语言开发的通用工具类库为其他Go项目提供常用的工具方法集合。
**📖 快速链接**
- [5分钟快速开始](./QUICKSTART.md)
- [数据库迁移指南](./MIGRATION.md) ⭐ 独立工具零耦合Docker友好
- [完整文档](./docs/README.md)
## 🌟 核心特性
### 🎯 **极简调用减少80%重复代码**
- **工厂黑盒模式**:一个配置文件,搞定所有服务初始化
- **Handler黑盒模式**统一的HTTP请求处理无需重复传递 `w``r`
- **中间件链式调用**:一行代码组合多个中间件
### 🚀 **生产级特性,开箱即用**
- **异步日志**:不阻塞请求,高并发性能
- **Panic恢复**自动捕获panic防止服务崩溃
- **令牌桶限流**保护API防止滥用
- **时区自动处理**:统一管理时区,避免时间错乱
### 🔧 **灵活可扩展**
- **默认配置即可用**:传 `nil` 使用默认配置
- **完全可定制**:每个功能都支持自定义配置
- **无侵入设计**:可以独立使用任何模块
### 📦 **零外部依赖(核心功能)**
- email、sms 使用 Go 标准库实现
- 可选依赖gorm数据库、redis、minio
## 功能模块
### 1. 数据库迁移工具 (migration)
提供数据库迁移功能支持MySQL、PostgreSQL、SQLite等数据库。
**🎯 独立工具,零耦合**
- ✅ 编译成独立二进制:`go build -o bin/migrate cmd/migrate/main.go`
- ✅ 生产环境无需Go环境只需二进制文件
- ✅ 与应用代码完全解耦,可独立部署和执行
- ✅ 支持宿主机和Docker零额外配置
### 2. 日期转换工具 (datetime)
提供日期时间转换功能,支持时区设定和多种格式转换。
@@ -14,7 +47,13 @@
提供HTTP请求/响应处理工具包含标准化的响应结构、分页支持和HTTP状态码与业务状态码的分离。
### 4. 中间件工具 (middleware)
提供常用的HTTP中间件包括CORS处理和时区管理。
提供生产级HTTP中间件包括
- **CORS** - 跨域资源共享
- **Timezone** - 时区处理
- **Logging** - 请求日志记录(支持异步)
- **Recovery** - Panic恢复防止服务崩溃
- **RateLimit** - 请求限流(令牌桶算法)
- **Chain** - 中间件链式组合
### 5. 配置工具 (config)
提供从外部文件加载配置的功能支持数据库、OSS、Redis、CORS、MinIO等配置。
@@ -64,9 +103,107 @@ go get git.toowon.com/jimmy/go-common@v1.0.0
**版本管理说明请参考 [VERSION.md](./VERSION.md)**
---
## 📚 文档导航
- **[快速开始指南](./QUICKSTART.md)** ⭐ - 5分钟快速上手
- [完整文档](./docs/README.md) - 所有模块详细文档
- [故障排除](./TROUBLESHOOTING.md) - 常见问题解决
- [版本管理](./VERSION.md) - 版本发布说明
---
## 快速开始
### 1. 创建配置文件 `config.json`
```json
{
"database": {
"type": "mysql",
"host": "localhost",
"port": 3306,
"user": "root",
"password": "password",
"database": "mydb"
},
"redis": {
"host": "localhost",
"port": 6379
},
"logger": {
"level": "info",
"output": "both",
"filePath": "./logs/app.log",
"async": true
}
}
```
### 2. 使用工厂模式(最简单,推荐)
```go
package main
import (
"net/http"
"time"
"git.toowon.com/jimmy/go-common/factory"
"git.toowon.com/jimmy/go-common/middleware"
commonhttp "git.toowon.com/jimmy/go-common/http"
)
func main() {
// 从配置文件创建工厂
fac, _ := factory.NewFactoryFromFile("./config.json")
// 获取logger
logger, _ := fac.GetLogger()
defer logger.Close()
// 配置中间件
chain := middleware.NewChain(
middleware.Recovery(&middleware.RecoveryConfig{Logger: logger}),
middleware.Logging(&middleware.LoggingConfig{Logger: logger}),
middleware.RateLimitByIP(100, time.Minute),
middleware.CORS(nil),
middleware.Timezone,
)
// 注册API路由
http.Handle("/api/hello", chain.ThenFunc(handleHello))
// 启动服务
http.ListenAndServe(":8080", nil)
}
func handleHello(w http.ResponseWriter, r *http.Request) {
h := commonhttp.NewHandler(w, r)
// 使用工厂记录日志
// fac.LogInfo("Hello API called")
// 返回响应
h.Success(map[string]interface{}{
"message": "Hello, World!",
"timezone": h.GetTimezone(),
})
}
```
### 3. 运行项目
```bash
go run main.go
# 访问 http://localhost:8080/api/hello
```
## 使用示例
详细的使用说明请参考各模块的文档:
- **[数据库迁移完整指南](./MIGRATION.md)** ⭐ - 独立工具,零耦合
- [数据库迁移工具文档](./docs/migration.md)
- [日期转换工具文档](./docs/datetime.md)
- [HTTP Restful工具文档](./docs/http.md)
@@ -80,21 +217,28 @@ go get git.toowon.com/jimmy/go-common@v1.0.0
### 快速示例
#### 数据库迁移
```go
import "git.toowon.com/jimmy/go-common/migration"
#### 数据库迁移(独立工具,零耦合)⭐
```bash
# 1. 复制模板templates/migrate/main.go -> cmd/migrate/main.go
# 2. 编译(生产环境推荐)
go build -o bin/migrate cmd/migrate/main.go
migrator := migration.NewMigrator(db)
migrator.AddMigration(migration.Migration{
Version: "20240101000001",
Description: "create_users_table",
Up: func(db *gorm.DB) error {
return db.Exec("CREATE TABLE users ...").Error
},
})
migrator.Up()
# 3. 使用
./bin/migrate up # 使用默认配置
./bin/migrate up -config /path/to/config.json # 指定配置
./bin/migrate status # 查看状态
# 迁移文件migrations/20240101000001_create_users.sql
# CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT, ...);
# Docker 中使用(挂载配置,修改无需重启)
# volumes:
# - ./config.json:/app/config.json:ro
# command: sh -c "./migrate up && ./server"
```
**详细说明**[数据库迁移完整指南](./MIGRATION.md) 📖
#### 日期转换
```go
import "git.toowon.com/jimmy/go-common/datetime"
@@ -120,23 +264,53 @@ func GetUser(h *commonhttp.Handler) {
http.HandleFunc("/user", commonhttp.HandleFunc(GetUser))
```
#### 中间件
#### 中间件(完整的生产级配置)
```go
import (
"time"
"git.toowon.com/jimmy/go-common/config"
"git.toowon.com/jimmy/go-common/logger"
"git.toowon.com/jimmy/go-common/middleware"
commonhttp "git.toowon.com/jimmy/go-common/http"
)
// CORS + 时区中间件
// 方式1简单配置使用默认设置
chain := middleware.NewChain(
middleware.CORS(),
middleware.Recovery(nil), // Panic恢复
middleware.Logging(nil), // 请求日志
middleware.RateLimit(nil), // 限流100请求/分钟)
middleware.CORS(nil), // CORS允许所有源
middleware.Timezone, // 时区处理
)
http.Handle("/api", chain.ThenFunc(yourHandler))
// 方式2生产级配置推荐
// 创建异步logger
myLogger, _ := logger.NewLogger(&config.LoggerConfig{
Level: "info",
Output: "both",
FilePath: "./logs/app.log",
Async: true, // 异步模式,不阻塞请求
})
chain := middleware.NewChain(
middleware.Recovery(&middleware.RecoveryConfig{
Logger: myLogger,
EnableStackTrace: true,
}),
middleware.Logging(&middleware.LoggingConfig{
Logger: myLogger,
SkipPaths: []string{"/health"},
}),
middleware.RateLimitByIP(100, time.Minute), // 100请求/分钟
middleware.CORS(nil),
middleware.Timezone,
)
handler := chain.ThenFunc(yourHandler)
// 在Handler中获取时区
// 在Handler中使用
func handler(h *commonhttp.Handler) {
timezone := h.GetTimezone()
timezone := h.GetTimezone() // 获取时区
h.Success(data)
}
```
@@ -276,3 +450,197 @@ go get git.toowon.com/jimmy/go-common@v1.0.0
**详细版本管理说明请参考 [VERSION.md](./VERSION.md)**
## 设计理念
### 1. 黑盒模式 - 减少重复代码
**问题**:传统方式需要在每个项目中重复编写初始化代码
```go
// ❌ 传统方式 - 需要在每个项目中重复
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(100)
sqlDB.SetMaxIdleConns(10)
// ... 更多配置
```
**解决**:工厂黑盒模式 - 配置文件搞定一切
```go
// ✅ 黑盒模式 - 一行代码搞定
db, _ := factory.NewFactoryFromFile("config.json").GetDatabase()
```
### 2. Handler模式 - 统一请求处理
**问题**:每个处理器都要传递 `w``r`
```go
// ❌ 传统方式
func GetUser(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
json.NewEncoder(w).Encode(data)
}
```
**解决**Handler封装 - 简洁优雅
```go
// ✅ Handler模式
func GetUser(h *commonhttp.Handler) {
id := h.GetQueryInt64("id", 0)
h.Success(data)
}
```
### 3. 中间件链 - 灵活组合
**问题**:中间件嵌套难以维护
```go
// ❌ 传统方式 - 嵌套地狱
handler := corsMiddleware(
timezoneMiddleware(
loggingMiddleware(
yourHandler
)
)
)
```
**解决**:链式调用 - 清晰明了
```go
// ✅ 链式组合
chain := middleware.NewChain(
middleware.CORS(),
middleware.Timezone,
middleware.Logging(nil),
)
handler := chain.ThenFunc(yourHandler)
```
## 最佳实践
### ✅ 推荐做法
1. **使用工厂模式**:通过配置文件统一管理所有服务
2. **使用异步日志**:生产环境开启 `Async: true`
3. **配置Recovery中间件**防止panic导致服务崩溃
4. **合理设置限流**:根据实际业务设置限流阈值
5. **使用时区中间件**:统一管理时区,避免时间错乱
### ❌ 避免做法
1. **不要在循环中创建logger**使用全局logger或工厂模式
2. **不要跳过健康检查日志**:高频接口应该配置 `SkipPaths`
3. **不要使用同步日志记录大量日志**:高并发场景使用异步模式
4. **不要在生产环境使用 `CORS: *`**:明确指定允许的源
## 性能优化建议
### 日志优化
```go
// ✅ 异步模式 - 高并发场景
loggerConfig := &config.LoggerConfig{
Async: true, // 异步写入
BufferSize: 1000, // 缓冲区大小
}
// ✅ 跳过高频接口
loggingConfig := &middleware.LoggingConfig{
SkipPaths: []string{"/health", "/metrics", "/ping"},
}
```
### 中间件顺序优化
```go
// ✅ 推荐顺序(从外到内)
chain := middleware.NewChain(
middleware.Recovery(cfg), // 1. 最外层捕获panic
middleware.Logging(cfg), // 2. 记录所有请求
middleware.RateLimit(cfg), // 3. 限流保护
middleware.CORS(cfg), // 4. CORS处理
middleware.Timezone, // 5. 时区处理
)
```
### 数据库连接池优化
```json
{
"database": {
"maxOpenConns": 100, // 最大连接数
"maxIdleConns": 10, // 最大空闲连接
"connMaxLifetime": 3600 // 连接最大生存时间(秒)
}
}
```
## 故障排除
### 问题1循环导入错误
**错误**`import cycle not allowed`
**解决**:使用 `middleware.NewCORSConfig()` 转换配置
```go
configCORS := cfg.GetCORS()
middlewareCORS := middleware.NewCORSConfig(
configCORS.AllowedOrigins,
configCORS.AllowedMethods,
configCORS.AllowedHeaders,
configCORS.ExposedHeaders,
configCORS.AllowCredentials,
configCORS.MaxAge,
)
```
### 问题2IDE显示导入错误
**错误**`could not import git.toowon.com/jimmy/go-common/logger`
**解决**重置Go模块缓存
```bash
go clean -modcache
go mod download
# 重启IDE的Language Server
```
### 问题3限流不生效
**原因**:分布式部署下,内存存储只在单机生效
**解决**分布式场景建议使用Redis实现限流
更多问题请查看 [TROUBLESHOOTING.md](./TROUBLESHOOTING.md)
## 贡献指南
欢迎贡献代码!请遵循以下步骤:
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 创建 Pull Request
## 许可证
MIT License
## 联系方式
- 作者Jimmy
- 邮箱jimmy@toowon.com
- 项目地址git.toowon.com/jimmy/go-common
---
⭐ 如果这个项目对你有帮助,请给个 Star