常见的页面优化技术
页面的优化技术分为:缓存和,页面静态化,静态资源优化,CDN优化等
其中缓存分为: 页面缓存+url缓存+对象缓存
页面缓存
也没缓存的时间比较短的。比如10秒钟的缓存时间失效
思路: 获取页面缓存,没有的时候重新获取页面然后进行渲染,然后返回
使用 Thymeleaf 的话,Springboot中有ThymeleafViewResolver可以帮助我们获取到页面的模板
ThymeleafViewResolver
这个方法可以得到一个模板的引擎,这个类的父类 TemplateEngine,其中的process方法是关键
其中的IContext这个类的参数,可以通过 SpringWebContext
SpringWebContext
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
渲染模板
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
Controller方法上加入produces="text/html"
重新我们之前的GoosController的商品列表
此时这个Controller方法返回的是一个页面,因此需要 @ResponseBody进行标记
/** * 使用页面缓存技术 * @param model * @param user * @return * @throws Exception */ @RequestMapping(value="/toListCache", produces="text/html") @ResponseBody public String toListWithPageCache(HttpServletRequest request, HttpServletResponse response,Model model , User user) throws Exception { if(user == null) { return "login"; } model.addAttribute("user", user); //获取页面缓存 RedisServiceProxy proxy = new RedisServiceProxy(GoodsKey.GOODS_LIST,redisService); String html = proxy.getBean("", String.class); if(!StringUtils.isEmpty(html)) { return html; } //查询商品信息 List<GoodsVo> goodsList = goodsService.listGoods(); model.addAttribute("goodsList", goodsList); //页面缓存的核心东西,渲染页面 SpringWebContext ctx = new SpringWebContext(request,response, request.getServletContext(),request.getLocale(), model.asMap(), applicationContext ); //手动渲染 html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx); if(!StringUtils.isEmpty(html)) { proxy.setBean("", html); } return html; }
查看redis
注意点
页面的缓存呢其实呢是user不一样而已,其他的对大部分用户来说是一样的。
但是呢如果是一个详情页面,那么就有问题了。
因此这也就是url缓存的概念了
也就是将用户在url中的参数作为页面缓存key的一部分。
这样不同的用户看到的详情页是不一样的
Url缓存
这个是对页面缓存的进一步利用,参数作为key的一部分。
比如我们的商品详情页面,url中有一个参数 商品id
/** * 使用缓存的例子 * @param model * @param user * @param goodsId * @return * @throws Exception */ @RequestMapping(value="/to_detailCache/{goodsId}",produces="text/html") @ResponseBody public String detailWithCache(HttpServletRequest request, HttpServletResponse response, Model model,User user, @PathVariable("goodsId")Long goodsId) throws Exception { model.addAttribute("user", user); //获取页面缓存 RedisServiceProxy proxy = new RedisServiceProxy(GoodsKey.GOODS_DETAIL,redisService); String html = proxy.getBean(""+goodsId, String.class); if(!StringUtils.isEmpty(html)) { return html; } GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId); model.addAttribute("goods", goods); long startAt = goods.getStartDate().getTime(); long endAt = goods.getEndDate().getTime(); long now = System.currentTimeMillis(); int miaoshaStatus = 0; int remainSeconds = 0; if(now < startAt ) {//秒杀还没开始,倒计时 miaoshaStatus = 0; //单位是毫秒 remainSeconds = (int)((startAt - now )/1000); }else if(now > endAt){//秒杀已经结束 miaoshaStatus = 2; remainSeconds = -1; }else {//秒杀进行中 miaoshaStatus = 1; remainSeconds = 0; } model.addAttribute("miaoshaStatus", miaoshaStatus); model.addAttribute("remainSeconds", remainSeconds); SpringWebContext ctx = new SpringWebContext(request,response, request.getServletContext(),request.getLocale(), model.asMap(), applicationContext ); html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx); if(!StringUtils.isEmpty(html)) { proxy.setBean(""+goodsId, html); } return html; }
对象缓存
将对象化成json然后存入到redis中再从redis中获取到就是对象缓存。
缓存中没有的时候才会查询数据库.
之前的User对象的获取就是这种形式的
更新注意缓存的更新
因此对于页面上的一些表示对象可以进行缓存。
但是呢如果遇到了更新的话,我们更新完数据库之后,要处理缓存的。
先更新数据库,然后更新缓存,保证缓存的一致性。
注意一定要更新数据库,之后再进行缓存的更新。
因为如果调用顺序之后呢,就会先加载缓存,然后更新,数据库的数据被更新了,是最新的,造成了数据不一致
注意了调用呢,一定要调用Service
service中可能是使用了缓存的,直接使用dao就可能造成这个缓存的不一致。
缓存的目的
减少对数据库的访问。
基本上保证在60秒内可以不访问 mysql数据库,直接从redis中获取的。
这样系统的负载就只体现在 java 和redis进程上面。
消灭掉mysql的负载