前言
此篇文章是系列的第五章篇文章,具体文章目录:
章节名称 | 博客地址 |
---|---|
安装部署Redis | 集成Redis(已完结) |
页面登陆功能设计 | 登录功能设计(更新优化中) |
秒杀页面具体设计 | 秒杀详情页(已完结) |
JMeter初级压测学习 | Jmeter压测入门学习(已完结) |
页面优化设计 | 页面优化设计(已完结) |
接口优化 | RabbbitMq接口优化(已完结) |
图形验证码等 | 图形验证码及接口防刷(更新优化中) |
在前面学习到了基础的登录功能模块的设计(还在继续完善中)以及Redis封装类的设置对应的是github源码miaosha_2的miaosha_2模块。对于模块三部分主要是关于秒杀商品页面的设计主要是权限设计和秒杀时间的倒计时设计后续会持续推出,这部分主要来讲述页面的优化部分的设计。
正文
对于秒杀业务的瓶颈大部分都是来源于数据库的设计,因为对于商品而言商家的增添,用户的购买减少商品的数量,以及用户的查询都是会访问到数据库,能够降低数据库的访问是我们在秒杀业务中要做的重中之重,所以这部分的页面优化我们主要考虑来减少对数据库的访问。
增加缓存
而第一种最有效减少对数据库的访问就是加缓存,通过各种粒度的缓存来实现减少对数据库的访问,通常用 页面缓存+ URL缓存+对象缓存,最大粒度的就是页面缓存,最小粒度的就是对象缓存。将这些缓存的信息缓存在Redis中,后面可以使用到RDM来进行具体查看,发现缓存了整个页面。
页面静态化,前后端分离
什么是页面静态化
:对于现在的很多的应用程序都是使用到JSP页面或是thymeleaf 模板解析也都是动态化的。静态化就是单纯的html页面,通过js,ajax来请求服务端,进行页面的渲染等。
好处
: 前面提到了使用页面缓存技术,但是客户端还是会请求服务端来进行页面的下载,但是若是做了页面的静态化,客户端就相当于缓存了前端的静态页面,不需要次次的请求都从服务端进行页面数据的下载。
页面缓存
概念简述: 当我们在访问一个页面的时候,并不是就会立马前往服务端请求页面数据的下载,而是先在缓存中查看有没有这个页面数据,若是存在就会返回给客户端,若是没有再去服务端请求数据手动渲染数据,返回给客户端,然后存在缓存中。所以就包含以下的三步:
- 去缓存
- 手动渲染模板
- 结果输出
实际操作
在我们实现页面缓存之前先来看一下之前是如何操作的,可以去github上下载源代码,对于前4部分是没有使用到页面缓存的,所以我们先来打开miaosha_4
模块看之前是如何将我们的商品列表给渲染出来的。
- 首先是访问固定的商品列表的url:
localhost:8080/goods/to_list
查看代码:key看到是访问到固定的url以后,会在进行一系列的Controller-> Service-> dao从数据库中取出数据,然后存在一个list中,放在model中返回给商品列表页,这个时候对于用户的每一次访问到前端页面都会进行数据库的请求,这个时候在高并发的情况下肯定是不实用的,所以我们要进行思考和更改。
如下是之前的操作:
@RequestMapping(value="/to_list")
public String list(Model model,MiaoshaUser user) {
model.addAttribute("user", user);
List<GoodsVo> goodsList = goodsService.listGoodsVo();
model.addAttribute("goodsList", goodsList);
return "goods_list";
}
这个时候就需要用到了thymeleafViewResolver 具体可以参看参看地址使用ctrl+f进行全局搜索。既然知道使用到这个,就需要我们使用*@Autowired*注入:
@Autowired
ThymeleafViewResolver thymeleafViewResolver;
然后使用到下面这个方法(这个方法就是用来做缓存功能):
thymeleafViewResolver.getTemplateEngine().process();
但是我们需要传参数,就可以使用到快捷键 ctrl+P查看需要什么具体的参数:
这里我们可能会疑惑,IContext
类型又是个什么类型呢,这个时候使用到双击shift
进行全局的搜索:
可以看到的是如下,然后我们点击进行:
点击进去之后使用快捷键ctrl+ alt+B查看相关的实现:查看与Spring相关联的配置(因为我们是Spring项目进行整合)。
可以发现若是我们想要使用SpringWebContext就需要传入参数呀,我们找到对应的实现,见下图:我们传入这些参数,然后new一个IContext
类型的对象传入到我们的函数中,才能够实现其功能。
代码如下:
@RequestMapping(value="/to_list", produces="text/html")
@ResponseBody
public String list(HttpServletRequest request, HttpServletResponse response, Model model,MiaoshaUser user) {
model.addAttribute("user", user);
//取缓存
String html = redisService.get(GoodsKey.getGoodsList, "", String.class);
if(!StringUtils.isEmpty(html)) {
return html;
}
List<GoodsVo> goodsList = goodsService.listGoodsVo();
model.addAttribute("goodsList", goodsList);
SpringWebContext ctx=new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),
model.asMap(),applicationContext);
// new了一个ctx 传入上面要求的参数,然后传入到process函数中即可返回我们的页面信息。
html=thy