- 优化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库引用
12 KiB
数据库与缓存系统
**本文档引用的文件** - [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)目录
- 项目结构
- MySQL 数据库集成与 ORM 配置
- Beego ORM 模型定义与自动迁移
- 事务处理模式
- Redis 缓存系统架构
- Redis 初始化与连接池管理
- 分布式缓存层设计
- 代理池状态存储机制
- 键值设计规范
- 数据库连接管理
- 缓存穿透与击穿应对策略
- 性能监控指标
项目结构
本项目采用分层架构设计,核心数据持久化与缓存组件集中于 internal 目录下。models 目录存放所有数据库实体模型,cache 目录封装
Redis 客户端,proxy 和 utils 目录分别实现代理池的两种状态存储方案。
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 : "关联银行卡"
图源
- internal/models/user/user_info.go
- internal/models/merchant/merchant_info.go
- internal/models/order/order_info.go
- internal/models/agent/agent_info.go
- internal/models/road/road_info.go
- internal/models/payfor/payfor_info.go
事务处理模式
系统通过 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.RWMutex对proxies映射进行读写保护,在获取新代理时加写锁,确保并发安全,防止同一时间大量请求穿透到代理服务API。
本节源码
性能监控指标
系统通过 otelTrace 模块集成 OpenTelemetry,对关键操作进行监控。日志中记录了代理获取、Redis操作、数据库查询等耗时,可用于分析性能瓶颈。例如,
GetProxy 函数被标记为一个Span,可以追踪其执行时间。
本节源码