# 基于SpringBoot的高并发选课系统
## 项目简介
本项目主要解决在高校选课场景下,保证选课系统在大量读写压力下不宕机,以及选课时尽可能提高选课QPS,给学生一个良好的选课体验,完成上述功能同时保证选课安全
## 运行效果图
![](image/img1.png)
![](image/img2.png)
![](image/img3.png)
![](image/img4.png)
![](image/img5.png)
其他效果图请到image文件夹中查看
## 技术选型
前端:Bootstrap、JQuery、Thymeleaf
后端:SpringBoot、Shiro、JPA、Caffeine
中间件:Redis、RabbitMQ、Druid
数据库:MySQL
## 优化思路
### 页面查看
解决思路:从Redis缓存中查看数据,减少数据库访问
从数据可见性角度来讲,分为对所有人可见的公有信息,和只有自己可见的私有信息
#### 公有信息
**不变动:** 必修课课程表中的数据是不变动,一般展现的是该专业学生本学期所必选的的课程信息,这类信息不发生变动,缓存到Redis中,缓存时间为一天
**变动:**
1. 必修课课程一般对应好几个授课计划,以高数来讲,这个课可能会对应好几个授课教师以及好几个时段的授课计划,但这类必修课授课计划学校一般会为学生预选,只有少部分学生因不满意授课时段或授课老师会去退课并重新选课,所以这类数据变动频率小,Redis缓存一分钟
2. 选修课授课计划一般是一个课程对应一个授课计划,因为是选修课,所以学校不为学生预选,需要学生自己选,所以这块并发压力大,数据变化频繁,Redis缓存一分钟
**_缺点:_** 学生看到的课程余量存在延迟,可能已经选完了,但列表上还显示有课,因此会在学生第一次进入选课页面提醒学生数据有延迟
**_特有优化:_** 数据库在加载授课计划信息时,只会加载有余量的课程
#### 私有信息
**不变动:** 考试查询和成绩查询,这类数据不会发生变动,学生看个几次就不会再看了,Redis缓存30分钟
**变动:** 选课结果,在选课初期学生可能频繁查看选课结果,Redis缓存30分钟
**_特有优化:_** 选课结果按时间降序排序,优先展示最新选的课程
### 登陆
1. 学生可能多次登陆系统,第一次登陆时将学生信息加载进Redis,减少后续登陆时对数据库的访问
2. 通过单例模式构建全局唯一类,根据sessionID保存学生学号,供后续使用
### 选课
**_此功能为整个系统的重点优化之处,_** 主要分为两大步骤,选课安全验证和执行选课操作
#### **选课安全验证**
1. IP限流,每分钟可以访问三次,与学号绑定,通过Redis实现
```java
Integer sno = StudentIDUtils.getStudentIDFromMap();
Integer count = (Integer) redisService.get("ip-", String.valueOf(sno));
if (count == null) {
//一分钟内可以访问三次
redisService.set("ip-", String.valueOf(sno), 1, 1, TimeUnit.MINUTES);
}else if (count < 3){
redisService.incr("ip-"+sno, 1);
}else {
throw new GlobalException(CodeMsg.COUNT_OVER);
}
```
2. 判断是否存在该课程,从Redis中查看
3. 判断是否在规定选课时限范围内,从Redis中查看
4. 若满足上述步骤,根据课程号生成其md5值,暴露秒杀地址
5. 执行选课操作时验证秒杀地址是否正确
#### 执行选课操作
1. 通过本地标记判断是否有余量,若有,执行后续
2. 判断是否重选,通过查看Redis是否有对应缓存来实现
3. 判断上课时间是否冲突,构造冲突判断算法,遍历Redis中已选课程进行验证
4. 库存预减,当库存为0时,将该授课计划添加到本地缓存中,本地缓存通过Caffeine构建
```java
Long num = redisService.hdecr("forPlanCount", String.valueOf(pno), 1);
// LOGGER.info("redis中读取pno={} 的授课计划余量为{}", pno, num);
if(num < 0){
//没余量,写入本地缓存中
caffeineCache.put(pno, true);
throw new GlobalException(CodeMsg.PlAN_OVER);
}
```
5. 选课请求压入MQ,异步执行,流量削峰,消费端消费选课信息,将结果写入数据库,结果写入数据库这一步采用事务机制,先插入结果,后减余量,减少事务期间锁持有时间,优化数据库读写性能
6. 返回执行成功标识,但结果需要到选课查询页面确认
#### 预加载
```java
@Service
public class ChooseServiceImpl implements ChooseService, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
//预加载相关操作
}
}
```
通过上述代码所示,Spring在生成Bean初期,会将选课所需要的相关数据加载到Redis中
#### 超选
```java
//选课
@Modifying
@Query("update PlanEntity p set p.num = p.num-1 where p.pno =?1 and p.num > 0")
Integer reduceNumByPno(Integer pno);
```
### 退课
1. 到Redis中查看是否存在该条选课记录
2. 删除该条选课记录,对应授课计划余量加一(事务,减少锁持有时间)
3. 修改Redis中对应数据,余量加一,删除掉该条选课记录
4. 返回退课成功标识
### 其他优化点
**安全相关:** 存储在数据库中的密码和选课链接都经过了MD5加密,对应MD5值的生成经过了两次加盐
**数据库操作:** 引入Druid数据库连接池,提升对数据库的操作性能
## 压力测试
测试内容:选课QPS
测试技术:Jmeter
测试环境:MacBook Pro2018,JDK1.8,Jmeter 5.3
测试计划:理想状态下(余量充足,不存在重复选课,上课时间不冲突等),同时执行5000个线程(模仿5000个同学),选同一节课,看选课执行情况
测试方案:
1. 利用mysql存储过程生成5000个学生学号,并将数据导出为cvs格式,供Jmeter使用
```mysql
delimiter //
create procedure createSno ()
begin
declare i int;
set i = 1;
while i <= 5000 do
insert into testData values(i);
set i = i + 1;
end while;
end //
delimiter ;
call createSno();
```
2. 使用Jmeter图形化界面生成测试方案,验证测试方案可行性
![](image/jmeter/img1.png)
3. 使用Jmeter命令行压测(图形化界面仅用来做验证,并不适合高负载压测),执行5次,查看结果
```
jmeter -n -t [xuanke.jmx,测试文件] -l [xuanke.txt,结果输出] -e -o [/test,web输出]
```
![](image/jmeter/img2.png)
### 压测结果说明
多次压测后得出来的平均选课qps为500出头,读页面的平均选课qps为900多
备注:为了简化测试,测试时修改了部分代码,主要是去除url校验和写死pno
没有合适的资源?快使用搜索试试~ 我知道了~
毕业设计 基于SpringBoot的高并发选课系统源码+部署文档+全部数据资料(优秀项目).zip
共139个文件
java:54个
png:18个
js:16个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 109 浏览量
2024-04-23
10:47:45
上传
评论
收藏 5.93MB ZIP 举报
温馨提示
【资源说明】 毕业设计 基于SpringBoot的高并发选课系统源码+部署文档+全部数据资料(优秀项目).zip毕业设计 基于SpringBoot的高并发选课系统源码+部署文档+全部数据资料(优秀项目).zip 【备注】 1、该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
资源推荐
资源详情
资源评论
收起资源包目录
毕业设计 基于SpringBoot的高并发选课系统源码+部署文档+全部数据资料(优秀项目).zip (139个子文件)
bootstrap.css 143KB
bootstrap.min.css 118KB
style.min.css 105KB
materialdesignicons.min.css 85KB
font-awesome.css 37KB
font-awesome.min.css 32KB
bootstrap-theme.css 26KB
bootstrap-theme.min.css 23KB
layer.css 14KB
layer.css 5KB
dashboard.css 2KB
signin.css 906B
materialdesignicons.eot 286KB
fontawesome-webfont.eot 162KB
glyphicons-halflings-regular.eot 20KB
loading-0.gif 6KB
loading-2.gif 2KB
loading-1.gif 701B
.gitignore 499B
common.html 12KB
major.html 8KB
elective.html 8KB
result.html 7KB
clazz.html 6KB
kaoshi.html 5KB
grade.html 5KB
login.html 5KB
index.html 2KB
RedisUtil.java 14KB
ChooseServiceImpl.java 11KB
ResultServiceImpl.java 5KB
RedisConfig.java 5KB
LoginController.java 4KB
PlanEntity.java 4KB
ClazzServiceImpl.java 3KB
GradeEntity.java 3KB
ClazzEntity.java 2KB
RabbitMQConfig.java 2KB
RedisServiceImpl.java 2KB
StudentEntity.java 2KB
KaoShiServiceImpl.java 2KB
GradeServiceImpl.java 2KB
KaoShiEntity.java 2KB
DruidConfig.java 2KB
StudentIDUtils.java 2KB
ChooseController.java 2KB
ClazzController.java 2KB
ShiroConfig.java 2KB
ResultInfoController.java 2KB
StudentServiceImpl.java 2KB
UserRealm.java 2KB
ResultEntity.java 2KB
CodeMsg.java 1KB
MD5Util.java 1KB
KaoShiController.java 1KB
GradeController.java 1KB
ListDTO.java 1KB
MQReceiver.java 971B
ResultDTO.java 957B
RedisService.java 946B
PlanRepository.java 898B
MQSender.java 895B
ChooseTimeEntity.java 807B
MvcConfig.java 725B
ExposerDTO.java 691B
CaffeineConfig.java 631B
ResultPK.java 611B
ChooseService.java 586B
ResultService.java 562B
ResultRepository.java 536B
KaoShiRepository.java 406B
GradeRepository.java 402B
ClazzService.java 371B
GlobalException.java 352B
XuankeApplication.java 323B
UUIDUtil.java 320B
StudentRepository.java 295B
ClazzRepository.java 289B
ChooseTimeRepository.java 242B
KaoShiService.java 238B
GradeService.java 234B
StudentService.java 168B
feather.min.js 155KB
jquery.min.js 82KB
bootstrap.js 68KB
bootstrap.min.js 36KB
layer.js 22KB
jquery.validate.min.js 21KB
popper.min.js 19KB
perfect-scrollbar.min.js 18KB
additional-methods.min.js 17KB
md5.min.js 10KB
common.js 5KB
main.min.js 5KB
layer.js 3KB
messages_zh.min.js 1KB
dashboard.js 953B
npm.js 484B
LICENSE 2KB
bootstrap.min.css.map 529KB
共 139 条
- 1
- 2
资源评论
不走小道
- 粉丝: 3338
- 资源: 5059
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- training_plan_db.sql
- 2c4f3adc7be59975e81fa0c1f24cb6ea.JPG
- python爬虫入门,分享给有需要的人,仅供参考
- 722bf4c3ee17fa231ad9efcb12407aa0.JPG
- 15da2b5d3ceeddc8af2f6a7eed26d7e0.JPG
- 7ae59002be36a13ad6de32c4e633a196.JPG
- spark中文文档,spark操作手册以及使用规范
- WPF-Halcon算法平台,类似于海康威視VisionMater.zip
- Fake Location,可用来王者荣誉修改战区及企业微信定位打卡等
- the fire level NULL
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功