Files
kami_gateway/.qoder/repowiki/zh/content/技术栈与依赖/数据库与缓存系统/数据库与缓存系统.md
danial ea089b7be8 docs(wiki): 更新API参考文档格式与内容
- 优化API参考文档的段落排版和表格对齐
- 补充签名机制和支付接口的详细说明- 完善错误码与解决方案的描述
- 统一文档中的代码引用和示例格式

docs(beego):优化Beego框架集成文档结构

- 改进Beego框架文档的换行和段落布局
- 完善控制器继承和中间件集成的说明
- 优化ORM模型注册和路由机制的描述- 统一文档中的技术术语表达方式

docs(docker): 改进Docker部署指南文档格式

- 优化Dockerfile多阶段构建的描述
- 完善docker-compose配置文件说明
- 改进本地部署步骤和故障排除指南- 统一文档中的命令行示例格式feat(supplier): 新增LianIns卡发送任务类型- 在枚举中添加SendCardTaskTypeEnumLianIns类型
- 更新GetAllSendCardTaskType函数返回值
- 实现LianIns任务类型的工厂方法

chore(deps): 更新项目依赖版本

- 升级github.com/bytedance/sonic至v1.14.2
- 升级github.com/duke-git/lancet/v2至v2.3.8
- 升级github.com/bytedance/sonic/loader至v0.4.0
- 移除natefinch/lumberjack和yaml.v2依赖- 清理间接依赖中的toml库引用
2025-11-04 16:04:08 +08:00

12 KiB
Raw Blame History

数据库与缓存系统

**本文档引用的文件** - [main.go](file://main.go) - [conf/app.conf](file://conf/app.conf) - [internal/models/init.go](file://internal/models/init.go) - [internal/cache/redis.go](file://internal/cache/redis.go) - [internal/config/cfg_model.go](file://internal/config/cfg_model.go) - [internal/utils/proxy_pool.go](file://internal/utils/proxy_pool.go) - [internal/proxy/proxy_pool.go](file://internal/proxy/proxy_pool.go)

目录

  1. 项目结构
  2. MySQL 数据库集成与 ORM 配置
  3. Beego ORM 模型定义与自动迁移
  4. 事务处理模式
  5. Redis 缓存系统架构
  6. Redis 初始化与连接池管理
  7. 分布式缓存层设计
  8. 代理池状态存储机制
  9. 键值设计规范
  10. 数据库连接管理
  11. 缓存穿透与击穿应对策略
  12. 性能监控指标

项目结构

本项目采用分层架构设计,核心数据持久化与缓存组件集中于 internal 目录下。models 目录存放所有数据库实体模型,cache 目录封装 Redis 客户端,proxyutils 目录分别实现代理池的两种状态存储方案。

graph TD
subgraph "核心模块"
Models[models/]
Cache[cache/]
Proxy[proxy/]
Utils[utils/]
end
subgraph "配置"
Conf[conf/app.conf]
end
subgraph "ORM与驱动"
BeegoORM[github.com/beego/beego/v2/client/orm]
MySQLDriver[github.com/go-sql-driver/mysql]
end
subgraph "Redis客户端"
GoRedis[github.com/redis/go-redis/v9]
end
Conf --> Models
Conf --> Cache
MySQLDriver --> BeegoORM
BeegoORM --> Models
GoRedis --> Cache
Cache --> Proxy
Cache --> Utils

图源

MySQL 数据库集成与 ORM 配置

系统通过 Beego ORM 框架集成 MySQL 数据库,使用 github.com/go-sql-driver/mysql 作为底层驱动。数据库连接信息从 conf/app.conf 文件中读取,并在程序启动时完成初始化。

sequenceDiagram
participant Main as main.go
participant Models as models/init.go
participant Config as config
participant ORM as Beego ORM
participant MySQL as MySQL Driver
Main->>Models : init()
Models->>Config : 读取 mysql : : dbhost, dbuser, dbpasswd, dbbase, dbport
Config-->>Models : 返回配置值
Models->>Models : 构建 DSN 连接字符串
Models->>ORM : RegisterDriver("mysql", orm.DRMySQL)
Models->>ORM : RegisterDataBase("default", "mysql", DSN)
Models->>ORM : 设置 orm.Debug
Models->>ORM : RegisterModel(所有实体)
ORM->>MySQL : 建立连接

图源

本节源码

Beego ORM 模型定义与自动迁移

models 目录下的各子包(如 accounts, merchant, order 等)定义了具体的数据库实体。每个实体结构体通过 orm.RegisterModel()init() 函数中注册Beego ORM 会根据结构体字段自动生成对应的数据库表。

classDiagram
class UserInfo {
+int Id
+string Username
+string Email
+string Password
+datetime CreatedAt
+IsActive() bool
}
class MerchantInfo {
+int Id
+string MerchantId
+string MerchantKey
+string Status
+float64 Balance
}
class OrderInfo {
+int Id
+string MerchantOrderId
+string BankOrderId
+float64 OrderAmount
+string Status
+string RoadUid
}
class AgentInfo {
+int Id
+string AgentId
+string Level
+float64 CommissionRate
}
class RoadInfo {
+int Id
+string RoadUid
+string RoadName
+string Status
+int Concurrency
}
class PayforInfo {
+int Id
+string PayforId
+string BankCardId
+float64 Amount
+string Status
}
UserInfo <|-- MerchantInfo : "继承"
MerchantInfo --> OrderInfo : "拥有"
MerchantInfo --> AgentInfo : "代理"
OrderInfo --> RoadInfo : "使用通道"
PayforInfo --> BankCardInfo : "关联银行卡"

图源

事务处理模式

系统通过 Beego ORM 的 orm.NewOrm() 方法获取事务对象,支持显式事务控制。在需要保证数据一致性的业务场景(如订单创建、资金变动)中,使用 Begin()Commit()Rollback() 方法管理事务。

flowchart TD
Start([开始事务]) --> CreateOrm["orm.NewOrm()"]
CreateOrm --> Begin["Begin()"]
Begin --> ExecuteSQL["执行多条SQL语句"]
ExecuteSQL --> Success{"操作成功?"}
Success --> |是| Commit["Commit()"]
Success --> |否| Rollback["Rollback()"]
Commit --> End([事务提交])
Rollback --> End

本节源码

Redis 缓存系统架构

Redis 在系统中扮演双重角色:作为 internal/cache 的分布式缓存层,加速高频数据读取;作为 internal/utils/proxy_pool.go 中代理池的状态存储管理代理IP的生命周期。

graph TB
subgraph "Redis 双重角色"
subgraph "分布式缓存层"
CacheLayer[internal/cache]
CacheLayer --> RedisClient[RedisClient]
RedisClient --> RedisServer[(Redis)]
end
subgraph "代理池状态存储"
ProxyPool[internal/utils/proxy_pool.go]
ProxyPool --> RedisClient
ProxyPool --> OrderBasedProxyStrategy[OrderBasedProxyStrategy]
OrderBasedProxyStrategy --> ProxiesMap["proxies map[string]*ProxyInfo"]
end
end
CacheLayer --> |高频数据读取| RedisServer
ProxyPool --> |状态存储| RedisServer

图源

Redis 初始化与连接池管理

Redis 客户端通过 cache.Start() 函数进行单例初始化。该函数使用 sync.OnceFunc 确保全局唯一实例,从配置中读取连接参数,并建立与 Redis 服务器的连接。

sequenceDiagram
participant App as 应用启动
participant Cache as cache.Start()
participant Config as config.GetConfig()
participant Redis as RedisClient
App->>Cache : Start()
Cache->>Config : GetRedisConfig()
Config-->>Cache : Host, Password, DB
Cache->>Redis : NewRedisClient(Host, Password, DB)
Redis->>Redis : redis.NewClient(&Options)
Redis->>Redis : Ping() 测试连接
alt 连接成功
Redis-->>Cache : 返回 *RedisClient 实例
Cache->>Cache : redisClientInstance = 实例
else 连接失败
Cache->>Logger : 记录错误 "redis 连接失败"
end

图源

本节源码

分布式缓存层设计

internal/cache 包提供了一个封装的 RedisClient 结构体,对 github.com/redis/go-redis/v9 客户端进行了二次封装,提供了更便捷的 API。该层支持字符串、列表、Stream 等多种数据结构的操作,并内置了序列化/反序列化功能。

classDiagram
class RedisClient {
-Client *redis.Client
+Set(ctx, key, value, expiration) error
+Get(ctx, key, value) error
+Delete(ctx, key) error
+Exists(ctx, key) (bool, error)
+LPush(ctx, key, values...) error
+RPopUnmarshal(ctx, key, value) error
+XAdd(ctx, key, values) (string, error)
+XReadUnmarshal(ctx, key, start, count, block) ([]map[string]interface{}, error)
+Close() error
}
class RedisClient 的使用
RedisClient 的使用 --> OrderPoolServiceImpl : "匹配订单"
RedisClient 的使用 --> NuclearImpl : "核弹卡密"
RedisClient 的使用 --> ProxyPool : "代理状态"

图源

代理池状态存储机制

internal/utils/proxy_pool.go 实现了一个基于订单号和通道的代理策略(OrderBasedProxyStrategy)。它使用内存中的 map[string]*ProxyInfo 来缓存代理IP并通过 StartProxyPool() 函数启动。该策略支持跨通道复用代理IP以满足 OrderPerIP 配置的需求。

flowchart TD
Start([GetProxy]) --> CheckCache["检查缓存 proxies[\"channel_orderID\"]"]
CheckCache --> |存在且有效| ReturnCached["返回缓存代理"]
CheckCache --> |不存在或过期| GetNew["获取新代理"]
GetNew --> CallAPI["调用代理服务API"]
CallAPI --> |成功| StoreCache["存入缓存 proxies[\"channel_orderID\"]"]
StoreCache --> ReturnNew["返回新代理"]
CallAPI --> |失败| Retry["重试最多3次"]
Retry --> ReturnError["返回错误"]
ReturnCached --> End([返回代理])
ReturnNew --> End

图源

本节源码

键值设计规范

系统遵循清晰的键值命名规范以确保数据的可维护性和可读性。Redis 键通常采用 domain:subdomain:identifier 的格式。

键前缀 用途 示例 TTL
nuclear_random_ids: 核弹卡密的随机ID与指纹映射 nuclear_random_ids:abc123 永久 (0)
channel_orderID 代理池缓存键 appleCard_order_123 50-55秒
customer_order_pool: 用户订单池 customer_order_pool:road123:100.00 动态
produce_order_pool: 供应订单池 produce_order_pool:road123:100.00 动态

本节源码

数据库连接管理

数据库连接由 Beego ORM 在 init() 函数中统一管理。通过 RegisterDataBase() 注册默认数据库连接,并使用全局的 orm.Debug 标志控制SQL日志输出。所有数据访问操作都通过 orm.NewOrm() 获取的 ORM 实例进行。

本节源码

缓存穿透与击穿应对策略

系统通过以下策略应对缓存问题:

  • 缓存穿透:对于 nuclear_random_ids 这类键即使Redis中不存在也会生成一个临时ID和指纹作为兜底避免大量请求直接打到数据库。
  • 缓存击穿OrderBasedProxyStrategy 使用 sync.RWMutexproxies 映射进行读写保护在获取新代理时加写锁确保并发安全防止同一时间大量请求穿透到代理服务API。

本节源码

性能监控指标

系统通过 otelTrace 模块集成 OpenTelemetry对关键操作进行监控。日志中记录了代理获取、Redis操作、数据库查询等耗时可用于分析性能瓶颈。例如 GetProxy 函数被标记为一个Span可以追踪其执行时间。

本节源码