目录

一、业务简介

二、人才培养方案(教学计划)设计

三、开课和选课前置操作

四、选课功能实现与技术选型

1.传统模式(直接操作数据库)

2.参考“秒杀”系统的设计

3.Redis + Lua解决原子性问题


一、业务简介

一般采用学分制的教学班比较灵活,一个教学班里可能会有不同年级,不同专业甚至不同课程性质(同一个教学班课程对一个同学是必修,可能对另外一个是选修)的学生,而采用学年制的可能就没这么复杂,一般是一个行政班就在一个教学班上课。但是不管是采用学分制还是学年制,归根到底还是要有教学班和学生的数据关系。

二、人才培养方案(教学计划)设计

培养方案设计应该考虑扩展性,针对学生不同的培养方式要有不同的培养方案。设计表时要预留有扩展的字段。 建议人才培养方案结构设计得不要太复杂,数据表不要太多,不然后面关联查询表太多,查询慢,可考虑冗余一些字段。 可以这样设计:培养方案下面直接关联课程(培养方案课程),课程有课程性质(必修已修这样的)和开课单位属性。培养方案里每个课程性质的课程的总学分可以比毕业要求的该课程性质的学分要高一些,这样学生只需要选择里面的一部分课程满足毕业要求即可。同时最好培养方案下面的课程不要挂太多,如果太多会导致后面学生和教学班的关系数据量很大。

三、开课和选课前置操作

开课时就是把培养方案课程生成为教学班数据,根据业务情况,如果有需要可以给教学班设置面向对象(就是设置这个教学班能被哪些年级或者哪些专业或者其他条件的学生能选),不管有多少业务,也不管业务多复杂,最后就要生成一个学生和教学班的关系表,也就是每个学生能选到哪些教学班。这个学生和教学班关系数据不必要实时生成,只要在任何会影响这个关系数据的地方发送消息到消息队列即可,表示需要同步该学生的教学班数据。例如,有个学生转专业了,或者留级了,这样会导致学生的培养方案会变,该学生关联的教学班也会变。在执行该学生转专业或者留级操作之后发送一条消息到消息队列,消息队列慢慢消费,重新根据这个学生的最新学籍数据来生成该学生相关的教学班数据。

在选课之前,学生和教学班关系数据应该已经都有了,这些数据就是选课的源数据。选课过程就是学生从该学生的学生教学班关系表选中一部分课程,选课结果就是生成学生和已选教学班结果表,可以看做是往教学班里塞学生。 考虑到并发量问题,选课可以分批进行,选课批次绑定教学班,指定每个选课批次只能选哪些教学班,选课批次有时间限制。这样就可以起到分批限流的作用。

四、选课功能实现与技术选型

当已有学生和教学班关系数据时,选课就变得比较简单了,只要在页面展示学生能选到的教学班,然后学生选自己想要的教学班,选中确定后后台直接保存选课结果即可。其实现功能方式可以有好几种。

1.传统模式(直接操作数据库)

直接读取数据库中学生和教学班关系表数据,根据当前选课批次查询该选课批次的且是该学生自己关联的教学班数据供学生选课。学生在前端页面点击确认选课,后台保存选课即可。

但是实际高校的选课可能要满足2~3万学生同时在线选课的要求,本身选课就会有一些查询校验操作,例如选择的当前课程是否和学生已选课程上课时间冲突,某个课程性质的课只能选几门或者多少学分,已选课程是否已超过学生当前学期的学分上限,选择的教学班是否还有余量等等业务校验。最重要的是还要保证选教学班的人数不能超过课容量(类似“超卖”问题)。当选课有这些复杂业务查询校验的时候,并发量一高,可能数据库就支撑不了。如果数据库能顶得住这些压力,那可以采用这种方式。如果数据库支撑不住就要开始考虑其他的技术实现。

2.参考“秒杀”系统的设计

“秒杀”系统的设计建议去看尚硅谷的谷粒商城项目视频(项目视频资料都是开源的)。

参考商城的“秒杀”系统设计,把需要的数据全部都提前存入到redis,然后选课时都是从redis读取和修改数据。选课要做成一个单独的应用,消费选课队列的应用也是单独的应用。

大致的步骤为:①选课前按选课批次把数据存入redis,把选课时需要用到的数据都存入redis;②学生在选课界面看到的数据都是当前时间在选课批次的选课时间范围之内的,全部从redis查询数据;③选课时后台的查询数据校验也都是从redis里查询数据,确定选课的选课记录也要存在redis里;④选课成功后发送数据给消息队列,消息队列排队消费,选课结果存到数据库;

补充说明:①存在redis里的数据要设计好数据类型,比如教学班数据转json后按hash存在redis,为的是方便可以批量获取减少io次数,教学班的上课节次和学生的上课节次可以按set存,set有方法可以判断是否有交集数据,学生的学分上限数据也可以按hash存,方便获取单个属性;②每个教学班课程数据都应该设置个随机码,以防学生在选课之前就开始刷选课数据;③教学班余量可以设计成信号量;④要存每个学生的选课列表到redis,且要有选课状态字段,这样才知道哪些教学班课程是已选未选,为的是不用从数据库查询是否已选;⑤消息队列(rabbitMq)要设置开启发送端消息抵达Broker确认,开启发送端消息抵达Queue确认,开启消费端手动确认,要保证数据不丢失;⑥redis要做cluster集群或者sentinel模式;

测试效果如下:

选课耗时大概35ms左右

退选的逻辑这里不再多详细,逻辑大概与选课反着来就是了。耗时差不多。

问题:这种选课方式虽然全程不读取数据库了,但是选课时多次写redis数据,且还要发送消息队列数据,怎么保证这些redis操作的原子性?如果前面的和redis的IO操作成功了,但是后面又失败了,这怎么处理?

3.Redis + Lua解决原子性问题

优化上面的架构,把选课时所有的redis操作都写到Lua脚本里,Lua脚本执行是原子性的。把之前的选课代码按Lua语法重新写一遍即可。

这里注意一些问题:①可以把Lua脚本里的代码看成是一个方法,最后执行完后要返回数据,可以封装成一个对象(Lua里叫table),可以有成功失败标记,失败错误信息和成功返回的要发送给mq的数据(封装成一个table),执行成功后返回string,JSON转成对象即可拿到结果;②如果用Lua脚本那redis集群不用用cluster,因为一个Lua脚本的所有redis操作的key只能在一个hash槽,可以考虑用sentinel模式;③Lua脚本可能会有一些坑,做的时候要多测试和做好数据校验,Lua的一些坑参照这个:redis使用lua脚本回滚失败的原因_CRUD的W的博客-CSDN博客_lua redis 回滚;

改Lua脚本后测试效果如下:

时间不超过10ms,快了近10倍。

所以采用这种模式,只要redis服务器性能够,2~3万学生同时在线选课的压力应该是没问题。

但这种模式还是可以优化的,既然选课应用没有用到事务型数据库,那可以引入Spring Reactor响应式编程,可以将选课,退选和查询可选等进行改造,这个留下次再改造试试。

高校选课系统设计(一)相关推荐

  1. (附源码)ssm基于jsp高校选课系统 毕业设计 291627

    摘 要 本论文主要论述了如何使用JAVA语言开发一个高校选课系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述高校选课系统的当前背 ...

  2. 计算机毕业设计Java在线选课系统设计(系统+程序+mysql数据库+Lw文档)

    计算机毕业设计Java在线选课系统设计(系统+程序+mysql数据库+Lw文档) 计算机毕业设计Java在线选课系统设计(系统+程序+mysql数据库+Lw文档) 本源码技术栈: 项目架构:B/S架构 ...

  3. (附源码)ssm高校选课系统 毕业设计 291627

    ssm高校选课系统 摘 要 本论文主要论述了如何使用JAVA语言开发一个高校选课系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述 ...

  4. ssm基于jsp高校选课系统毕业设计源码291627

    摘 要 本论文主要论述了如何使用JAVA语言开发一个高校选课系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述高校选课系统的当前背 ...

  5. asp毕业设计——基于asp+sqlserver的网上选课系统设计与实现(毕业论文+程序源码)——网上选课系统

    基于asp+sqlserver的网上选课系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+sqlserver的网上选课系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦 ...

  6. 基于SSM+LayUI带兴趣推荐学生选课系统设计

    开发软件:Eclipse,也可Idea 数据库:mysql 开发技术:SSM + LayUI 基于SSM的高校在线选课系统设计和实现中主要分为前端用户功能模块和后台管理员功能模块,其中前端用户分为学生 ...

  7. [附源码]Java计算机毕业设计SSM高校选课系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  8. java计算机毕业设计高校选课系统源码+mysql数据库+系统+lw文档+部署

    java计算机毕业设计高校选课系统源码+mysql数据库+系统+lw文档+部署 java计算机毕业设计高校选课系统源码+mysql数据库+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开 ...

  9. java计算机毕业设计web高校车辆调度系统设计与实现MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计web高校车辆调度系统设计与实现MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计web高校车辆调度系统设计与实现MyBatis+系统+LW文档+源码+调试部 ...

最新文章

  1. JavaScript初学者编程题(20)
  2. SpringOSGINoDM项目的插件说明
  3. python语言入门p-python入门基础教程04 Python程序基本组成
  4. 算法1-排序LowB三人组
  5. tcp/ip详解--ttl
  6. CVPR 2020 《Where Does It Exist: Spatio-Temporal Video Grounding for Multi-Form Sentences》论文笔记
  7. MOCTF-Web-没时间解释了
  8. C#using static
  9. a算法和a*算法的区别_详解SPWM与SVPWM的原理、算法以及两者的区别
  10. Ehcache学习总结(3)--Ehcache 整合Spring 使用页面、对象缓存
  11. Android Drawable文件夹对应像素密度
  12. 入行||转行软件测试?写给迷惘的你
  13. matlab状态空间法算反馈阵,matlab中已知系统的状态方程怎样绘制系统阶跃响应曲线...
  14. C语言随笔小算法:单项链表如何实现队列
  15. oracle 字符串等于,ORACLE in (字符串,字符串,字符串)
  16. appscan无法连接到服务器_GTA5无法连接R星服务器怎么解决?无法连接解决方法
  17. matlab 陈学松,基于强化学习的空调系统运行优化OPTIMIZATIONOF-同济大学.PDF
  18. 南山驿站机器人_fc机器人大战钢铁之魂攻略
  19. 未来是否繁花似锦,源自我们当下之努力
  20. 2020-09-22

热门文章

  1. DenseFuse: A Fusion Approach to Infrared and Visible Images
  2. OSChina 周五乱弹 ——程序员脱单攻略!
  3. caffe代码阅读8: Data_layers的实现细节(各个数据读取层的实现细节) 2016.3.25-28
  4. 【JavaWeb】JSP(172-190)
  5. 申宝股票-家居和家电板块大涨
  6. 自动驾驶仿真(六)—— SIL软件在环仿真测试
  7. 【02月25日】【精彩电影合集】【15部】【亲测】【Lsyq5647发布】
  8. 三种对等式网络 文件服务器,对等式端到端网络的资源共享机制的特点
  9. 计算机视觉cv(1)
  10. echart简单应用