请求中的“开源节流”
近期的开发涉及到考核系统,后台人员负责出题,而相应的用户则打开浏览器答题。早期的系统中,用户在考试开始的时候,试卷在浏览器中的展现完全依靠后端来渲染,使用struts生成整个页面,然后发送至浏览器,用户才能答题。这种模式的问题不言而喻,因为是一个考试系统,在考试开始的一瞬间,1000个用户同时点击“打开”按钮,服务器处理每一个用户的请求,再来生成一个成型的页面,这中间要消耗很多服务器的资源,效率十分低下,经常会导致五分之一的用户打不开考卷。
二期的开发中,为了分摊服务器的压力,把整个卷面的渲染工作交给了浏览器端,使用ajax获取各种考题的json数据后,通过js来把每一个题型都解析出来,大大提高了效率。
遗留的问题:
当然也不能说,二期的优化已经十分完美了,还是有一些瑕疵,一份完整的考卷总共有五种题型:单选,多选,判断,填空,问答。现有的实现是,通过五次ajax请求来把每一种题型的数据请求回来,然后再渲染出来(整份试卷),问题是,一个用户会有5次请求,100个用户就会有500次请求,1000个用户就会有5000次请求!!而且是在,一个整点(考试开始的时间)3分钟范围内。所以,对于整个优化效果来说,优化的程度还不是很完美,服务器还是“亚历山大”。
下一步的优化:
下一步的优化有两个思路:1,合并请求;2,异步(按需)加载试题;3,预加载;
合并请求:
在把每一种题型的流量大小统计一番后,得出如下结论:
单选:0.53KB/个; 多选:0.55KB/个; 判断:0.26KB/个; 填空:0.25KB/个; 问答:0.87KB/个
这些流量是纯文本的流量,如果说某个题中有图片,那么也只是img标签所占用的文本空间,图片的下载不需考虑,考虑一份通用的试卷情况。
单选-15道;多选-10道;判断-5道;填空-5道;问答-3道;(每一个题型的单个题分值为:2, 2, 2, 2, 10)
那么每种题型的总流量为:
1,单选:7.95KB;
2,多选:5.5KB;
3,判断:1.3KB;
4,填空:1.25KB;
5,问答:2.61KB
我的目标是要把这五次请求消减成两次(为什么是两次,而不是合并成一次,考虑到了后台数据的处理,还有短时间内请求数量比较多的时候,小数据流量的短连接请求的成功率还是要比大数据量的长链接成功率要高些),而且在大数据量的情况下,每个请求的数据流量要基本持平,所以我们采用(1+3) && (2 + 4 + 5)的形式来请求各种题型。这两个请求的请求流量基本持平,单次9KB左右。
这个请求组合的数据解析相对来说比单题型的要复杂一些,但是我们赢得了效率,分担了服务器的压力。
异步(按需)加载(不考虑合并请求):
现有的实现是在获取考题信息的时候一次性的获取整个页面(五种题型),但是如果一个考卷的题目数量太多怎么办?按需加载可以解决,在初次打开页面,只展现单选题,再做完单选,自动加载多选,以此类推,用什么方式不重要,关键是要实现“按需加载”试题,这样同样可以分担服务器的压力;
预加载:
具体思路是,在考试前5分钟内,系统会在考卷的准备页面中获取考题信息的json数据(整体或者部分),先放入本地存储,到指定时间再把每一个题型解析出来,这样用户就不用等待请求的过程,只需等待解析的过程,但是本地的解析是很快的。