字节跳动后端技术训练营
如何去介绍这个训练营?
第 7 期训练营
项目内容
第 8 期训练营
背景
该训练营要求完成一个具有成员、登录、排课、选课共四个功能模块的系统。
任务
根据笔试成绩,我被分配为小组长,给小组成员安排各个模块。其中,我最初负责抢课模块,后由于一名组员的退出,我又负责了排课模块。
工作
排课模块包含创建课程、获取课程信息、绑定和解绑老师课程、获取老师课程、排课六个部分。抢课模块包含了学生抢课和学生课表两个功能。其中比较难的点在于抢课,也是我主动选择的模块。不过,这部分字节方需求并没有特别明确,因此我在我考虑范围内选择了最可能的方式,也算是对这次训练营的一些不满。
抢课模块的设计
- 2 个部分,抢课功能的实现,数据持久化的实现。
- 抢课功能方面:
- 学生 ID 是否存在、课程 ID 是否存在、学生是否重复选课、学生尝试抢课
- 数据库不支持高并发 → map,但不支持持久化,系统重启丢失,后续数据扩展不方便 → redis。
- redis 三种数据:(1)学生 ID 列表 (2)学生已选课列表 (3)课程剩余容量
- 学生 ID 列表 - 学生 ID 是否存在
- (2)和(3)是复合操作,为此借用 lua 来使 Redis 原子操作
- 先重复选课,后课程剩余容量。
- 保证不出现超卖的情况,将课程容量设为-1,来尽可能避免缓存穿透。
- 数据持久化方面:
- 初,同步方式。
- 后,协程异步方式。
- 后,管道方式,出错数据重新加入管道。
- 后,有界管道可能堵塞。某时刻,管道满,消费者取数据,生产者放数据,消费失败加入管道,堵塞住,进而也无法消费消息。
- 后,日志打印出来。
不使用 lua。先 desc 后获取结果,如果结果为负数,那么+1 回去。如果学生选上这个课,再+1 回去。
检测超卖
使用 python 生成的数据,每个学生从 1-30 数字中随机选择 10 次,作为 10 次请求,生成了 100 个学生的数据,存放到 csv 文件中,供 jmeter 工具读取数据。在缓存中设置课程容量,每个课程容量为 20. 设置 jmeter 在 5 秒钟内发送,检查缓存并没有出现容量为-1 的情况。