首页 > 其他分享 >计算机毕业设计——基于SpringBoot的高并发选课系统

计算机毕业设计——基于SpringBoot的高并发选课系统

时间:2024-07-23 10:56:38浏览次数:16  
标签:缓存 授课 SpringBoot 选课 数据库 Redis 学生 毕业设计

基于SpringBoot的高并发选课系统

私信获取完整代码

项目简介

本项目主要解决在高校选课场景下,保证选课系统在大量读写压力下不宕机,以及选课时尽可能提高选课QPS,给学生一个良好的选课体验,完成上述功能同时保证选课安全

运行效果图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

其他效果图请到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实现
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);
        }
  1. 判断是否存在该课程,从Redis中查看
  2. 判断是否在规定选课时限范围内,从Redis中查看
  3. 若满足上述步骤,根据课程号生成其md5值,暴露秒杀地址
  4. 执行选课操作时验证秒杀地址是否正确
执行选课操作
  1. 通过本地标记判断是否有余量,若有,执行后续
  2. 判断是否重选,通过查看Redis是否有对应缓存来实现
  3. 判断上课时间是否冲突,构造冲突判断算法,遍历Redis中已选课程进行验证
  4. 库存预减,当库存为0时,将该授课计划添加到本地缓存中,本地缓存通过Caffeine构建
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);
        }
  1. 选课请求压入MQ,异步执行,流量削峰,消费端消费选课信息,将结果写入数据库,结果写入数据库这一步采用事务机制,先插入结果,后减余量,减少事务期间锁持有时间,优化数据库读写性能

  2. 返回执行成功标识,但结果需要到选课查询页面确认

预加载
@Service
public class ChooseServiceImpl implements ChooseService, InitializingBean {
  @Override
    public void afterPropertiesSet() throws Exception {
      //预加载相关操作
    }
}

通过上述代码所示,Spring在生成Bean初期,会将选课所需要的相关数据加载到Redis中

超选
//选课
    @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使用
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();
  1. 使用Jmeter图形化界面生成测试方案,验证测试方案可行性

在这里插入图片描述

  1. 使用Jmeter命令行压测(图形化界面仅用来做验证,并不适合高负载压测),执行5次,查看结果
jmeter -n -t [xuanke.jmx,测试文件] -l [xuanke.txt,结果输出] -e -o [/test,web输出]

在这里插入图片描述

压测结果说明

多次压测后得出来的平均选课qps为500出头,读页面的平均选课qps为900多

备注:为了简化测试,测试时修改了部分代码,主要是去除url校验和写死pno

标签:缓存,授课,SpringBoot,选课,数据库,Redis,学生,毕业设计
From: https://blog.csdn.net/hxx56324/article/details/140618335

相关文章

  • SpringBoot项目打包成war包
    1.项目场景使用SpringBoot开发项目,由于内置了Tomcat,所以项目可以直接启动,部署到服务器的时候,直接打成jar包,就可以运行了。 有时需要把项目打包放入外置的Tomcat或者TongWeb中运行,就需要把项目打包成war包,。2.实现步骤2.1将启动类的pom文件打包方式更改为war<......
  • ssm乡村救助信息管理系统 计算机专业毕业设计源码44889
    摘要随着行业规模的不断壮大,信息变得越来越多。同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个BS结构的乡村救助信息管理系统来管理乡村救助信息,会使管理工作系统化、规范化,也会提高政府形象,提高管理效率。SSM乡村救助信息管理系统的主要使用者......
  • 宠物电商平台小程序 毕业设计-附源码37159
                                    目 录摘要1绪论1.1研究背景1.2研究现状1.3springboot框架介绍2 宠物电商平台小程序系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程3.3.2......
  • python+flask计算机毕业设计鲜花坊销售平台(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着电子商务的迅猛发展,线上购物已成为人们日常生活的重要组成部分,尤其在追求生活品质与个性化的今天,传统鲜花销售行业正经历着深刻的变革......
  • python+flask计算机毕业设计快递驿站管理系统(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着电子商务的迅猛发展,快递行业迎来了前所未有的繁荣期,快递包裹量急剧增长,对快递末端配送服务提出了更高的要求。传统的快递配送模式面临......
  • 基于springboot的水产养殖系统
    博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实实在在的写点程序。......
  • java毕业设计-基于springboot+vue的校园二手交易系统,基于java的校园二手交易系统,基于j
    文章目录前言演示视频项目背景项目架构和内容获取(文末获取)具体实现截图前台功能管理后台技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站前言博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • 初用IDEA的springboot第五步
    使用日志先配置文件,在resources下新建一个log4j.properties,将以下内容粘贴进去##设置###stdout,log4j.rootLogger=all,D,E,stdout##输出信息到控制台###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appe......
  • 基于java+springboot+vue实现的公司日常考勤系统(文末源码+Lw)132
     基于SpringBoot+Vue的实现的公司日常考勤系统(源码+数据库+万字Lun文+流程图+ER图+结构图+开题报告+演示视频+软件包)选题背景及意义:分析企业的考勤管理系统过程可以看到,考勤管理系统中主要要解决的是:1.考勤信息的管理;2.考勤、出勤信息的请假及申请;3.给系统设定用户登录权......
  • Springboot宠物领养商城
    详细运行视频地址宠物领养商城_哔哩哔哩_bilibili1.可注册可登录2.首页-》可浏览热销商品,可查看用户发布的帖子,可查看热门资讯3.宠物商城-》宠物详情,可购买,可加入购物车,可展示评价4.宠物领养-》可查看用户发布的领养的帖子,可留言评论5.平台资讯-》可查看管理员发布的资讯......