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

6.9 KiB
Raw Permalink Blame History

数据持久化与异步任务处理集成 - 架构说明

功能编号: 002-gorm-postgres-asynq
更新日期: 2025-11-13


系统架构概览

                            ┌─────────────────┐
                            │   Load Balancer │
                            │     (Nginx)     │
                            └────────┬────────┘
                                     │
                    ┌────────────────┼────────────────┐
                    │                │                │
          ┌─────────▼────────┐ ┌───▼──────────┐ ┌──▼─────────┐
          │   API Server 1   │ │ API Server 2 │ │   API N    │
          │  (Fiber:8080)    │ │(Fiber:8080)  │ │(Fiber:8080)│
          └─────────┬────────┘ └───┬──────────┘ └──┬─────────┘
                    │              │               │
                    └──────────────┼───────────────┘
                                   │
                    ┌──────────────┼──────────────┐
                    │              │              │
              ┌─────▼────┐    ┌───▼───────┐ ┌───▼─────────┐
              │PostgreSQL│    │   Redis   │ │Worker Cluster│
              │ (Primary)│    │ (Queue)   │ │  (Asynq)    │
              └────┬─────┘    └───────────┘ └─────────────┘
                   │
            ┌──────▼──────┐
            │ PostgreSQL  │
            │  (Replica)  │
            └─────────────┘

双服务架构

API 服务 (cmd/api/)

职责:

  • HTTP 请求处理
  • 业务逻辑执行
  • 数据库 CRUD 操作
  • 任务提交到队列

特点:

  • 无状态设计,支持水平扩展
  • RESTful API 设计
  • 统一错误处理和响应格式
  • 集成认证、限流、日志中间件

Worker 服务 (cmd/worker/)

职责:

  • 从队列消费任务
  • 执行后台异步任务
  • 任务重试管理
  • 幂等性保障

特点:

  • 多实例部署,自动负载均衡
  • 支持多优先级队列
  • 优雅关闭(等待任务完成)
  • 可配置并发数

分层架构

Handler 层 (internal/handler/)

职责: HTTP 请求处理

- 请求参数验证
- 调用 Service 层
- 响应封装
- 错误处理

设计原则:

  • 不包含业务逻辑
  • 薄层设计
  • 统一使用 pkg/response/

Service 层 (internal/service/)

职责: 业务逻辑

- 业务规则实现
- 跨模块协调
- 事务管理
- 错误转换

设计原则:

  • 可复用的业务逻辑
  • 支持依赖注入
  • 使用 pkg/errors/ 错误码

Store 层 (internal/store/)

职责: 数据访问

- CRUD 操作
- 查询构建
- 事务封装
- 数据库交互

设计原则:

  • 只返回 GORM 原始错误
  • 不包含业务逻辑
  • 支持事务传递

Model 层 (internal/model/)

职责: 数据模型定义

- 实体定义
- DTO 定义
- 验证规则

数据流

CRUD 操作流程

HTTP Request
    ↓
Handler (参数验证)
    ↓
Service (业务逻辑)
    ↓
Store (数据访问)
    ↓
PostgreSQL
    ↓
Store (返回数据)
    ↓
Service (转换)
    ↓
Handler (响应)
    ↓
HTTP Response

异步任务流程

HTTP Request (任务提交)
    ↓
Handler
    ↓
Service (构造 Payload)
    ↓
Queue Client (Asynq)
    ↓
Redis (持久化)
    ↓
Worker (消费任务)
    ↓
Task Handler (执行任务)
    ↓
PostgreSQL/外部服务

核心设计决策

1. 为什么使用 GORM?

优势:

  • Go 生态最成熟的 ORM
  • 自动参数化查询(防 SQL 注入)
  • 预编译语句缓存
  • 软删除支持
  • 钩子函数支持

2. 为什么使用 golang-migrate?

理由:

  • 版本控制: 每个迁移有版本号
  • 可回滚: up/down 脚本
  • 团队协作: 迁移文件可 review
  • 生产安全: 明确的 SQL 语句

不用 GORM AutoMigrate:

  • 无法回滚
  • 无法删除列
  • 生产环境风险高

3. 为什么使用 Asynq?

优势:

  • 基于 Redis无需额外中间件
  • 任务持久化(系统重启自动恢复)
  • 自动重试(指数退避)
  • Web UI 监控asynqmon
  • 分布式锁支持

关键技术实现

幂等性设计

方案 1: Redis 锁

key := constants.RedisTaskLockKey(requestID)
if exists, _ := rdb.SetNX(ctx, key, "1", 24*time.Hour).Result(); !exists {
    return nil // 跳过重复任务
}

方案 2: 数据库唯一约束

CREATE UNIQUE INDEX idx_order_id ON tb_order(order_id);

方案 3: 状态机

if order.Status != "pending" {
    return nil // 状态不匹配,跳过
}

事务管理

func (s *Store) Transaction(ctx context.Context, fn func(*Store) error) error {
    return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
        txStore := &Store{db: tx, logger: s.logger}
        return fn(txStore)
    })
}

连接池配置

PostgreSQL:

  • MaxOpenConns: 25最大连接
  • MaxIdleConns: 10空闲连接
  • ConnMaxLifetime: 5m连接生命周期

Redis:

  • PoolSize: 10
  • MinIdleConns: 5

扩展性设计

水平扩展

API 服务:

  • 无状态设计
  • 通过负载均衡器分发请求
  • 自动扩缩容K8s HPA

Worker 服务:

  • 多实例连接同一 Redis
  • Asynq 自动负载均衡
  • 按队列权重分配任务

数据库扩展

读写分离:

Primary (写) → Replica (读)

分库分表:

  • 按业务模块垂直分库
  • 按数据量水平分表

监控与可观测性

健康检查

  • PostgreSQL Ping
  • Redis Ping
  • 连接池状态

日志

  • 访问日志: 所有 HTTP 请求
  • 错误日志: 错误详情
  • 慢查询日志: > 100ms
  • 任务日志: 提交/执行/失败

指标(建议)

  • API 响应时间
  • 数据库连接数
  • 任务队列长度
  • 任务失败率

安全设计

数据安全

  • SQL 注入防护GORM 参数化)
  • 密码哈希bcrypt
  • 敏感字段不返回(json:"-"

配置安全

  • 生产环境使用环境变量
  • 数据库 SSL 连接
  • Redis 密码认证

性能优化

数据库

  • 适当索引
  • 批量操作
  • 分页查询
  • 慢查询监控

任务队列

  • 优先级队列
  • 并发控制
  • 超时设置
  • 幂等性保障

参考文档