秒杀项目学习笔记 第五章————页面优化技术

秒杀项目学习笔记 第五章————页面优化技术

核心思路:减少对数据库的访问

5-1 页面缓存

特点:有效期往往比较短
1.取缓存,html存放在缓存中,可取出则
2.不可则 手动渲染模板 ,并且存放在redis中
3.结果输出

goods_list为例,在Controller中,添加注解,直接返回html

1
2
3
4
5
6
7
8
9
10
11
12
13
//取缓存,取到返回。html是长文本,一堆
String html = redisService.get(GoodsKey.getGoodsList, "", String.class);
if (!StringUtils.isEmpty(html)) {
return html;
}
//取不到,手动渲染并且加入到redis中,ThemleafViewResolver,
SpringWebContext ctx = new SpringWebContext(request, response, request.getServletContext(),
request.getLocale(), model.asMap(), applicationContext);//配置一下环境,下面会用到,配起来就是根据接口, 缺啥补啥
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);//选择模板(页面),进行渲染(成字符串)
if (StringUtils.isEmpty(html)) {
redisService.set(GoodsKey.getGoodsList, "", html);
}
return html;

时间一般较短,显示前两页

5-2 对象缓存(重点:更新对象缓存!!)

获取对象操作
比如user对象的缓存,对于对象,设置过期时间为永不过期。
1.取对象缓存
2.取为null则从数据库中取,并且写入redis缓存。
更新密码操作。
1.取对象(以上)
2.更新对象密码,update写入数据库,
3.更新缓存:删除原缓存,user.setPassword,user写入缓存

不能去调用其他类的DAO,只能调用其他类的Service,
Jmeter查询发现mysql的内存占用还是很高。

5-4 商品详情静态化、也就是前后端分离

常用技术AngularJs Vue.js
优点:利用浏览器的缓存

1.将goods_detail.htm放在resoucrse的static中,
2.将静态页面放在static中,后缀为htm,因为在application中配置了会去resources中寻找.html后缀
<td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>
3.在客户端写入异步获取请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$(function(){
//countDown();
getDetail();
});

function getDetail(){
var goodsId = g_getQueryString("goodsId");
$.ajax({ //异步访问客户端,获取参数
url:"/goods/detail/"+goodsId,
type:"GET",
success:function(data){
if(data.code == 0){
render(data.data);
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.msg("客户端请求有误");
}
});
}

5-5 秒杀静态化

1.改造后端,
不是 不停地model.addAttribute("orderInfo", orderInfo);
最后再返回”order_detail”客户端跳转,获取model熟悉

而是返回一个Result.success(orderInfo)表单,从客户端调用ajax跳转。然后取客户端传来的参数。

2.改造前端,前端goods_detail.htm的秒杀按钮,对应函数如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function doMiaosha(){

//点击了秒杀按钮后, ajax异步调用 发送表单请求(传goodsId),得到结果,success则跳转到订单详情,失败则,error
$.ajax({
url:"/miaosha/do_miaosha",
type:"POST",
data:{
goodsId:$("#goodsId").val(),
},
success:function(data){ //这里的data就是do_miaosha返回的Result了
if(data.code == 0){
window.location.href="/order_detail.htm?orderId="+data.data.id;//秒杀成功,跳转到订单详情//data.data就是vo
}else{
layer.msg(data.msg);
}
},
error:function(){
layer.msg("客户端请求有误");
}
});
}

秒杀返回的状态码是304,表示服务端表示你本地的页面没有变化,页面不用下载了,但是客户端与服务端还是有交互。

利用SpringBoot的 SPRING RESOURCES HANDLING

参考文档:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/

然后在浏览器访问一次后,后台就会判断,不会发生交互。直接返回200状态码。

5-6 订单详情静态化 解决超卖

生成的订单放到redis缓存中,秒杀判断是否已经生成订单的时候,可以不用去数据库查询了,直接从缓存中查询

超卖问题

秒杀逻辑: 1.先判断库存 >0 2.再判断是否已经秒杀过,也就是是否存在秒杀订单。
3.再减库存下订单。(这里再判断一下库存??)

问题:同一用户买多个
同一个用户两个请求,判断有库存,判断都没有秒杀,然后下了两个订单。
解决:更新加判断,并且秒杀订单表加唯一索引报错,秒杀事务回滚
优化1:给更新库存,减库存的时候加了一个判断。只在stock_count>0的情况下减库存。
优化2::对其数据表建立唯一索引,第二个订单就插不进表,从而报错,秒杀请求事务回滚。

5-7 静态资源优化

1.JS/CSS压缩, 减少流量(去掉空格之类)
2.多个JS/CSS组合,减少连接数
一般并发3 4个链接 从服务端获取资源,提高页面加载速度

淘宝:Tengine
http://tengine.taobao.org/
http://tengine.taobao.org/document_cn/http_concat_cn.html

webpack:打包前端文件

3.CDN就近访问
CDN:内容分发网络,把数据缓存到全网节点上,根据用户请求,分发到离用户最近(最快)的位置上。

瓶颈:数据库,所以要削减请求到数据库的数量

并发解决流程

用户开始:

  1. 浏览器页面静态化,缓存到浏览器端。
  2. 部署CDN节点,请求首先访问到就近CDN缓存,
  3. ngiinx缓存
  4. redis应用程序页面缓存 –对象缓存
  5. 数据库

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2019 Jae's blog All Rights Reserved.

UV : | PV :