
选课系统设计流程
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
选课系统设计
1. Redis 存储时间管理
- 存储开始时间和结束时间。
- 通过定时任务在到点时删除这两个 key,以开放选课。
2. Redis 缓存课堂信息
- 存储课堂信息(包括 ID、课程 ID、教师 ID、课堂限选人数)。
- 通过 Redisson 设置课堂信息的分布式信号量:
- Key:课堂 ID
- Value:限选人数
3. 学生选课流程
- 学生开始并发选课,点击选课按钮。
-
情况 1:如果 Redis 中
jwxt:xkmk:xkxx
没有数据,则插入数据(假设学生 ID 为 1001,课堂 ID 为 001):- 执行命令:
SET jwxt:xkmk:xkxx 1001-001 1
- 同时减少信号量数据:
boolean f = redisson.getSemaphore("001").tryAcquire(1);
- 执行命令:
-
情况 2:如果有数据但为 0,则修改数据:
- 执行命令:
SET jwxt:xkmk:xkxx 1001-001 1
- 同时减少信号量数据:
boolean f = redisson.getSemaphore("001").tryAcquire(1);
- 执行命令:
-
情况 3:如果有数据且为 1,则返回信息:已选该课程(前端应转换为退选按钮,但可能因网络抖动出现此情况)。
-
4. 学生退选流程
-
如果有数据且为 1,则插入数据(假设学生 ID 为 1001,课堂 ID 为 001):
- 执行命令:
SET jwxt:xkmk:xkxx 1001-001 0
- 同时增加信号量数据:
boolean f = redisson.getSemaphore("001").release();
- 为防止超出初始值,使用 Lua 脚本进行增加判断。
- 执行命令:
-
如果有数据但为 0,则提示:该课程已退选。
-
如果 Redis 中
jwxt:xkmk:xkxx
中没有对应数据,则返回信息:该课程未选。
5. 数据持久化与消息队列
-
将需要直接持久化到 MySQL 的数据(如选课单和退选单)放入消息队列(MQ)中。
- 示例:当用户 1001 先选了课堂 001(状态为 1),然后又点击退选(状态为 0),这些操作先在 Redis 中修改,同时将这两个操作放入 MQ。
-
根据用户 ID 1001 进行队列取模,确保每个用户的所有操作都在一个队列上,保证顺序消费。
-
消费者端加上分布式锁,锁粒度为用户课堂级别:
- Key:
user_lock_1001_101
- 确保每个用户在操作一个课堂的选课退选时上锁,但不影响其他操作,保证顺序消费和高并发。
- Key:
-
为了保证幂等性,防止消息重试导致的重复消费,添加 Redis 锁:
- Key:数据的唯一 ID
- 设置过期时间为 10 秒。
- 多个线程尝试持有锁,成功则执行操作,失败则放弃执行。
6. Redis 数据结构
-
String: 存储开始时间和结束时间
- Key:
kssj
- Value:
2024-10-03
- Key:
-
Hash: 存储课堂信息
- Key:
jwxt:xkmk:ktxx
- Field: 课堂 ID
- Value: 课堂信息 + 课程 ID + 教师 ID 的 JSON
- Key:
-
Hash: 存储选课信息
- Key:
jwxt:xkmk:xkxx
- Field: 课堂 ID + 学生 ID
- Value: 0/1(0 代表退选,1 代表已选)
- Key:
-
String: 存储课堂信息分布式信号量
- Key: 课程班随机码
- Value: 限选人数
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 王德明
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果