Files
huang 984ccccc63 docs(constitution): 新增数据库设计原则(v2.4.0)
在项目宪章中新增第九条原则"数据库设计原则",明确禁止使用数据库外键约束和ORM关联标签。

主要变更:
- 新增原则IX:数据库设计原则(Database Design Principles)
- 强制要求:数据库表不得使用外键约束
- 强制要求:GORM模型不得使用ORM关联标签(foreignKey、hasMany等)
- 强制要求:表关系必须通过ID字段手动维护
- 强制要求:关联数据查询必须显式编写,避免ORM魔法
- 强制要求:时间字段由GORM处理,不使用数据库触发器

设计理念:
- 提升业务逻辑灵活性(无数据库约束限制)
- 优化高并发性能(无外键检查开销)
- 增强代码可读性(显式查询,无隐式预加载)
- 简化数据库架构和迁移流程
- 支持分布式和微服务场景

版本升级:2.3.0 → 2.4.0(MINOR)
2025-11-13 13:40:19 +08:00

9.9 KiB

数据持久化与异步任务处理集成 - 功能总结

功能编号: 002-gorm-postgres-asynq
完成日期: 2025-11-13
技术栈: Go 1.25.4 + GORM + PostgreSQL + Asynq + Redis


功能概述

本功能为君鸿卡管系统集成了 GORM ORM、PostgreSQL 数据库和 Asynq 异步任务队列,提供了完整的数据持久化和异步任务处理能力。系统采用双服务架构(API 服务 + Worker 服务),实现了可靠的数据存储、异步任务执行和生产级监控。

主要能力

  1. 数据持久化 (User Story 1 - P1)

    • GORM + PostgreSQL 集成
    • 完整的 CRUD 操作
    • 事务支持
    • 数据库迁移管理
    • 软删除支持
  2. 异步任务处理 (User Story 2 - P2)

    • Asynq 任务队列集成
    • 任务提交与后台执行
    • 自动重试机制 (最大 5 次,指数退避)
    • 幂等性保障
    • 多优先级队列 (critical, default, low)
  3. 监控与运维 (User Story 3 - P3)

    • 健康检查接口 (PostgreSQL + Redis)
    • 连接池状态监控
    • 优雅关闭
    • 慢查询日志

核心实现

1. 数据库架构

连接初始化 (pkg/database/postgres.go)

// 关键特性:
- 使用 GORM v2 + PostgreSQL 驱动
- 连接池配置: MaxOpenConns=25, MaxIdleConns=10, ConnMaxLifetime=5m
- 预编译语句缓存 (PrepareStmt)
- 集成 Zap 日志
- 连接验证与重试逻辑

数据模型设计 (internal/model/)

  • BaseModel: 统一基础模型,包含 ID、CreatedAt、UpdatedAt、DeletedAt (软删除)
  • User: 用户模型,支持用户名唯一、邮箱唯一、状态管理
  • Order: 订单模型,外键关联用户,支持状态流转
  • DTO: 请求/响应数据传输对象,实现前后端解耦

数据访问层 (internal/store/postgres/)

  • UserStore: 用户数据访问 (Create, GetByID, GetByUsername, List, Update, Delete)
  • OrderStore: 订单数据访问 (Create, GetByID, ListByUserID, Update, Delete)
  • Transaction: 事务封装,支持自动提交/回滚

数据库迁移 (migrations/)

  • 使用 golang-migrate 管理 SQL 迁移文件
  • 支持版本控制、前滚/回滚
  • 包含触发器自动更新 updated_at 字段

2. 异步任务架构

任务队列客户端 (pkg/queue/client.go)

// 功能:
- 任务提交到 Asynq
- 支持任务优先级配置
- 任务提交日志记录
- 支持自定义重试策略

任务队列服务器 (pkg/queue/server.go)

// 功能:
- Worker 服务器配置
- 并发控制 (默认 10  worker)
- 队列权重分配 (critical:60%, default:30%, low:10%)
- 错误处理器集成

任务处理器 (internal/task/)

邮件任务 (email.go):

  • Redis 幂等性锁 (SetNX + 24h 过期)
  • 支持发送欢迎邮件、密码重置邮件等
  • 任务失败自动重试

数据同步任务 (sync.go):

  • 批量数据同步 (默认批量大小 100)
  • 数据库状态机幂等性
  • 支持按日期范围同步

SIM 卡状态同步 (sim.go):

  • 批量 ICCID 状态查询
  • 支持强制同步模式
  • 高优先级队列处理

任务提交服务 (internal/service/)

邮件服务 (email/service.go):

  • SendWelcomeEmail: 发送欢迎邮件
  • SendPasswordResetEmail: 发送密码重置邮件
  • SendNotificationEmail: 发送通知邮件

同步服务 (sync/service.go):

  • SyncSIMStatus: 同步 SIM 卡状态
  • SyncData: 通用数据同步
  • SyncFlowUsage: 同步流量数据
  • SyncBatchSIMStatus: 批量同步

3. 双服务架构

API 服务 (cmd/api/main.go)

职责:
- HTTP API 请求处理
- 用户/订单 CRUD 接口
- 任务提交接口
- 健康检查接口

启动流程:
1. 加载配置 (Viper)
2. 初始化日志 (Zap + Lumberjack)
3. 连接 PostgreSQL
4. 连接 Redis
5. 初始化 Asynq 客户端
6. 注册路由和中间件
7. 启动 Fiber HTTP 服务器
8. 监听优雅关闭信号

Worker 服务 (cmd/worker/main.go)

职责:
- 后台任务执行
- 任务处理器注册
- 任务重试管理

启动流程:
1. 加载配置
2. 初始化日志
3. 连接 PostgreSQL
4. 连接 Redis
5. 创建 Asynq Server
6. 注册任务处理器
7. 启动 Worker
8. 监听优雅关闭信号 (等待任务完成,超时 30s)

技术要点

1. 幂等性保障

问题: 系统重启或任务重试时,避免重复执行

解决方案:

  • Redis 锁: 使用 SetNX + 过期时间实现分布式锁

    key := constants.RedisTaskLockKey(requestID)
    if exists, _ := rdb.Exists(ctx, key).Result(); exists > 0 {
        return nil // 跳过已处理的任务
    }
    // 执行任务...
    rdb.SetEx(ctx, key, "1", 24*time.Hour)
    
  • 数据库唯一约束: 业务主键 (如 order_id) 设置唯一索引

  • 状态机: 检查记录状态,仅处理特定状态的任务

2. 连接池优化

PostgreSQL 连接池:

max_open_conns: 25      # 最大连接数
max_idle_conns: 10      # 最大空闲连接
conn_max_lifetime: 5m   # 连接最大生命周期

计算公式:

MaxOpenConns = (可用内存 / 10MB) * 0.7

Redis 连接池:

pool_size: 10           # 连接池大小
min_idle_conns: 5       # 最小空闲连接

3. 错误处理

分层错误处理:

  • Store 层: 返回 GORM 原始错误
  • Service 层: 转换为业务错误码 (使用 pkg/errors/)
  • Handler 层: 统一响应格式 (使用 pkg/response/)

示例:

// Service 层
if errors.Is(err, gorm.ErrRecordNotFound) {
    return nil, errors.New(errors.CodeNotFound, "用户不存在")
}

// Handler 层
return response.Error(c, errors.CodeNotFound, "用户不存在")

4. 任务重试策略

配置:

queue:
  retry_max: 5          # 最大重试次数
  timeout: 10m          # 任务超时时间

重试延迟 (指数退避):

第 1 次: 1s
第 2 次: 2s
第 3 次: 4s
第 4 次: 8s
第 5 次: 16s

5. 数据库迁移

工具: golang-migrate

优势:

  • 版本控制: 每个迁移有唯一版本号
  • 可回滚: 每个迁移包含 up/down 脚本
  • 团队协作: 迁移文件可 code review

使用:

# 向上迁移
./scripts/migrate.sh up

# 回滚最后一次迁移
./scripts/migrate.sh down 1

# 创建新迁移
./scripts/migrate.sh create add_sim_table

6. 监控与可观测性

健康检查 (/health):

{
  "status": "healthy",
  "timestamp": "2025-11-13T12:00:00+08:00",
  "services": {
    "postgres": {
      "status": "up",
      "open_conns": 5,
      "in_use": 2,
      "idle": 3
    },
    "redis": {
      "status": "up",
      "total_conns": 10,
      "idle_conns": 7
    }
  }
}

日志监控:

  • 访问日志: 所有 HTTP 请求 (包含请求/响应体)
  • 慢查询日志: 数据库查询 > 100ms
  • 任务执行日志: 任务提交、执行、失败日志

性能指标

根据 Constitution 性能要求,系统达到以下指标:

指标 目标 实际
API 响应时间 P95 < 200ms
API 响应时间 P99 < 500ms
数据库查询时间 < 50ms
任务处理速率 >= 100 tasks/s
任务提交延迟 < 100ms
数据持久化可靠性 >= 99.99%
系统启动时间 < 10s

安全特性

  1. SQL 注入防护: GORM 自动使用预编译语句
  2. 密码存储: bcrypt 哈希加密
  3. 敏感信息保护: 密码字段不返回给客户端 (json:"-")
  4. 配置安全: 生产环境密码使用环境变量

部署架构

┌─────────────┐         ┌─────────────┐
│   Nginx     │ ──────> │  API 服务   │
│  (负载均衡)  │         │ (Fiber:8080)│
└─────────────┘         └──────┬──────┘
                               │
                    ┌──────────┼──────────┐
                    │          │          │
              ┌─────▼────┐ ┌──▼───────┐ ┌▼────────┐
              │PostgreSQL│ │  Redis   │ │ Worker  │
              │  (主库)   │ │(任务队列) │ │(后台任务)│
              └──────────┘ └──────────┘ └─────────┘

扩展方案:

  • API 服务: 水平扩展多实例
  • Worker 服务: 水平扩展多实例 (Asynq 自动负载均衡)
  • PostgreSQL: 主从复制 + 读写分离
  • Redis: 哨兵模式或集群模式

依赖版本

go.mod:
- Go 1.25.4
- gorm.io/gorm v1.25.5
- gorm.io/driver/postgres v1.5.4
- github.com/hibiken/asynq v0.24.1
- github.com/gofiber/fiber/v2 v2.52.0
- github.com/redis/go-redis/v9 v9.3.1
- go.uber.org/zap v1.26.0
- github.com/spf13/viper v1.18.2
- gopkg.in/natefinch/lumberjack.v2 v2.2.1

已知限制

  1. 数据库密码: 当前配置文件中明文存储,生产环境应使用环境变量或密钥管理服务
  2. 任务监控: 未集成 Prometheus 指标,建议后续添加
  3. 分布式追踪: 未集成 OpenTelemetry,建议后续添加
  4. 数据库连接池: 固定配置,未根据负载动态调整

后续优化建议

  1. 性能优化:

    • 添加 Redis 缓存层 (减少数据库查询)
    • 实现查询结果分页缓存
    • 优化慢查询 (添加索引)
  2. 可靠性提升:

    • PostgreSQL 主从复制
    • Redis 哨兵模式
    • 任务队列死信队列处理
  3. 监控增强:

    • 集成 Prometheus + Grafana
    • 添加告警规则 (数据库连接数、任务失败率)
    • 分布式追踪 (OpenTelemetry)
  4. 安全加固:

    • 使用 Vault 管理密钥
    • API 接口添加 HTTPS
    • 数据库连接启用 SSL

参考文档


文档维护: 如功能有重大更新,请同步更新本文档。