1.增加互斥锁:保证缓存和数据库数据一致性
2.增加消费队列,保证mysql数据的正常保存
This commit is contained in:
@@ -105,19 +105,21 @@
|
||||
|
||||
**服务端缓存覆盖(与移动端直接相关的读路径)**
|
||||
|
||||
- **用户**:会员鉴权 `Auth::init` 优先读 Redis 中的 `user` 行快照,未命中再查库并回填;**余额、连胜、打码量等变更**后服务端会删除该用户缓存,下次请求重新加载。
|
||||
- **游戏配置**:`game_config` 按 `config_key` 缓存(如字典、`pick_max_number_count`、`withdraw_bet_flow_ratio`、连胜配置等);后台或脚本直连 `Db` 更新配置时,保存逻辑需调用 **`GameHotDataRedis::gameConfigForget($key)`**(已实现于模型事件及部分后台控制器),否则最长延迟为 TTL。
|
||||
- **对局**:当前活跃局、按 `id` 加载的局、以及「最新一条 `game_record`」(与 `order id desc limit 1` 一致)缓存;**开奖、封盘、新建下一期**等写库后会 **`gameRecordForget`**,保证关键状态尽快一致。
|
||||
- **用户**:会员鉴权优先读 Redis 中的 `user` 行快照,未命中再查库并回填。**余额、连胜、打码量等变更**落库后,统一经 **`GameHotDataCoordinator::afterUserCommitted($userId)`**:先 **`GameHotDataRedis::userReplaceCacheFromDb`** 与 DB 对齐,再向 Redis 写队列投递幂等刷新任务(见 `GameHotDataWriteQueue` / `GameHotDataQueueConsumer`),用于削峰而非替代同步回源。
|
||||
- **游戏配置**:`game_config` 按 `config_key` 缓存。后台直连 `Db` 更新时须 **`GameHotDataCoordinator::afterGameConfigKeyCommitted($key)`**(模型 `GameConfig` 事件与独立表单控制器已接入);独立保存接口在写入前对同一 `config_key` 使用 **`GameHotDataLock`(`TYPE_GAME_CONFIG`)** 互斥。勿仅删除缓存键而不回源,否则最长不一致窗口为 TTL。
|
||||
- **对局**:当前活跃局、按 `id` 的局、最新一条 `game_record` 等;写库后经 **`GameHotDataCoordinator::afterGameRecordCommitted`** 同步刷新相关 Redis 键并入队。开奖/封盘等路径另可按记录 id 使用 **`GameHotDataLock`(`TYPE_GAME_RECORD`)** 串行化。
|
||||
|
||||
**环境变量(示例见仓库根目录 `.env-example`)**
|
||||
|
||||
- `GAME_HOT_CACHE_ENABLED`:是否启用上述 Redis 热点缓存(`false` 时全程回退数据库)。
|
||||
- `GAME_HOT_CACHE_TTL_GAME_CONFIG` / `GAME_HOT_CACHE_TTL_GAME_RECORD` / `GAME_HOT_CACHE_TTL_USER`:各类缓存 TTL(秒);仍应以**写后失效**为主,TTL 仅作兜底。
|
||||
- `GAME_HOT_CACHE_TTL_GAME_CONFIG` / `GAME_HOT_CACHE_TTL_GAME_RECORD` / `GAME_HOT_CACHE_TTL_USER`:各类缓存 TTL(秒);**以写后同步回源为主**,TTL 仅作兜底。
|
||||
- `GAME_HOT_CACHE_ENABLE_WRITE_QUEUE` 及队列长度、消费进程间隔等:控制写库后的**幂等刷新任务**是否入队及背压策略(见 `config/game_hot_cache.php`)。
|
||||
|
||||
**一致性提示(联调/测试)**
|
||||
|
||||
- 在 TTL 窗口内,若存在**绕过模型事件、且未调用 forget** 的手工 SQL 改库,可能出现短时不一致;生产环境应避免。
|
||||
- 客户端仍可按 **§3.2 `dictionaryList` 的 `version`** 做本地缓存;服务端字典数据另有 Redis 加速,二者可同时存在。
|
||||
- 任何绕过协调入口、只改 DB 不调用 **`GameHotDataCoordinator`** 的手工脚本,都可能与 Redis 短期不一致;生产环境应避免。
|
||||
- **`POST /api/game/betPlace`** 扣款路径使用与后台钱包加减点相同的 **用户维度 Redis 锁**(`GameHotDataRedis::userAdminMutationLockTry`)及 **`WHERE coin = ?` 条件更新**,与并发派彩/后台调账互斥;失败时返回 **§4.2** 所列中文说明。
|
||||
- 客户端仍可按 **§3.2 `dictionaryList` 的 `version`** 做本地缓存;服务端字典另有 Redis 加速,二者可同时存在。
|
||||
|
||||
---
|
||||
|
||||
@@ -289,6 +291,10 @@
|
||||
- `balance_after`:string(含义:下单后余额)
|
||||
- `current_streak`:int(含义:下单后连胜快照)
|
||||
|
||||
**可能错误码(补充)**(其余见文档头部错误码分段;扣款与缓存一致性强相关):
|
||||
|
||||
- `5000`:系统繁忙;或 **用户 Redis 互斥锁**未获取(与后台钱包/并发写同一用户串行,文案与后台一致:「该用户正在被其他管理员操作(钱包/并发保存),请稍后再试」);或 **`coin` 条件更新**未命中(并发下注/派彩/后台已改余额:「扣款失败:该用户余额已被其他请求修改(如下注、派彩或其他管理员已保存),请刷新后重试」)。
|
||||
|
||||
> 说明:一键重复上一注、自动托管开启/停止均由前端控制,客户端在相应时机调用 `/api/game/betPlace` 即可完成,不再提供独立接口。
|
||||
|
||||
### 4.3 查询我的下注记录(最近1个月)
|
||||
|
||||
Reference in New Issue
Block a user