5.1 页面缓存
页面缓存到redis:
- 页面缓存到redis
- 已缓存 则从redis直接返回goodlist.html的源代码 return html
- 未缓存: 调用thymeleaf 手动渲染模板
-
- 手动渲染:springwecontext html = thymeleafViewResolver.getTemplateEngine().process(“good_list”, ctx) 缓存到redis
//取缓存
String html = redisService.get(GoodsKey.getGoodsDetail, ""+goodsId, String.class);
if(!StringUtils.isEmpty(html)) {
return html;
}
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx);
if(!StringUtils.isEmpty(html)) {
redisService.set(GoodsKey.getGoodsDetail, ""+goodsId, html);
}
return html;
5.2 对象缓存
将service层查询到的对象缓存到redis:
//取缓存
MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class);
if(user != null) {
return user;
}
//取数据库
user = miaoshaUserDao.getById(id);
if(user != null) {
redisService.set(MiaoshaUserKey.getById, ""+id, user);
}
return user;
每次修改对象的数据需要更新数据到数据库,让缓存失效,例如miaoshaUser修改密码(但是要更新token,因为token虽然存在redis但是定位不是缓存)。
重新打包jar,发布到服务器,top命令发现,原来mysql进程占用cpu变少。
jmeter测试发现,qps从原来的1200到2500几乎可以说是翻了一倍。
- 缓存最常用的pattern:
1、失效:从cache没有取到,去数据库取,成功后放回缓存。
2、命中:从cache取,返回cache。
3、更新:数据存到数据库中,成功后,让cache失效。
5.4 商品详情静态化
使用jquery页面静态化 ajax请求接口获得商品的数据,Vo对象。
关于Vo对象和Po对象的区别等https://www.cnblogs.com/kobelieve/p/6231451.html
5.5 秒杀静态化
请求秒杀,跳转的页面对订单数据进行异步请求。
配置spring的cache参数,调浏览器缓存。
spring.resources.add-mappings=true
spring.resources.cache-period= 3600 (浏览器缓存的时间 对应响应头cache-Control)
spring.resources.chain.cache=true
spring.resources.chain.enabled=true
spring.resources.chain.gzipped=true (压缩编码)
spring.resources.chain.html-application-cache=true
spring.resources.static-locations=classpath:/static/
5.6 订单详情页面静态化,解决超卖问题
静态化:利用ajax加载页面
解决超卖出现负数库存的问题:sql的语句 update 加一个条件 and stock_count > 0
解决同一个用户可以秒杀下单两个商品,在高并发场景下:秒杀订单表添加根据用户id和商品id哈希计算生成的唯一索引(存到redis),创建订单时若存在唯一索引则异常。