高并发优化之页面缓存与URL缓存

Posted 慕课训练营

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高并发优化之页面缓存与URL缓存相关的知识,希望对你有一定的参考价值。

在同一时间内有大量用户访问同一页面时,会对服务器造成很大的压力,为了应对这种压力,我们需要对项目进行一些优化,这种优化可以分为页面级优化,服务级优化以及Tomcat服务端优化。


这里我先记录页面优化的页面缓存与URL缓存。


一、页面缓存

商品列表页面由于所有的商品都可以在同一列表展现,所以这里可以做一个页面的缓存。

原本在控制层负责商品列表的方法如下:

@RequestMapping(value = "/to_list")public String list(HttpServletResponse response, Model model, MiaoshaUser user) { model.addAttribute("user", user); List<GoodsVo> goodsList = goodsService.listGoodsVos(); model.addAttribute("goodsList", goodsList);
return "goods_list";}


页面缓存的思路如下:

  • 客户端在访问一个页面时,先从缓存中查找是否有对应的页面的缓存

  • 如果没有缓存,则重新手动渲染界面。

思路很简单,接下来我们来实现它:

@RequestMapping(value = "/to_list",produces = "text/html")@ResponseBodypublic String list(HttpServletRequest request,HttpServletResponse response, Model model, MiaoshaUser user) { model.addAttribute("user", user); List<GoodsVo> goodsList = goodsService.listGoodsVos(); model.addAttribute("goodsList", goodsList);
//取缓存 String html = redisService.get(GoodsKey.goodsList, "", String.class); if (!StringUtils.isEmpty(html)) { return html; }
//如果缓存中没有就要手动渲染 WebContext webContext = new WebContext(request, response, request.getServletContext(),request.getLocale(),model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", webContext); //存入缓存 if (!StringUtils.isEmpty(html)) { redisService.set(GoodsKey.goodsList, "", html); } return html;}


上面代码中的我在@RequestMapping注解中加了produces属性,设置返回的数据类型为html类型。

我这个项目属于Spring Boot项目,前端所采用的是Thymeleaf,所以在手动渲染页面时,我可以注入框架自带的ThymeleafViewResolver进行手动渲染页面。

重新访问商品列表页面,发现可以成功显示原本界面,同时远程连接Linux上的Redis,查看是否已经写入了对应的缓存数据:

高并发优化之页面缓存与URL缓存

如上图所示,对应的值为我之前写过的html代码,至此,页面缓存成功实现。


二、URL缓存

URL缓存其实和页面缓存思路相同,二者的不同在于缓存中加入了URL

其实到这里URL缓存已经很好理解了,只需要在缓存的key中加上URL携带的参数就可以。

代码如下:

@RequestMapping(value = "/to_detail/{goodsId}", produces = "text/html")@ResponseBodypublic String detail(HttpServletRequest request, HttpServletResponse response, @PathVariable(value = "goodsId") long goodsId, Model model, MiaoshaUser user) { model.addAttribute("user", user);
// 取缓存 String html = redisService.get(GoodsKey.goodsDetail, ""+goodsId, String.class); if (!StringUtils.isEmpty(html)) { return html; }
GoodsVo goods = goodsService.getGoodsVoById(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);
// 如果缓存中没有就要手动渲染 WebContext webContext = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", webContext); // 存入缓存 if (!StringUtils.isEmpty(html)) { redisService.set(GoodsKey.goodsDetail, ""+goodsId, html); } return html;
}

上面的代码中,我使用@PathVariable注解在URL中加上了商品Id这个参数,同时在Redis的key中加上了这个参数,这样就实现了URL的缓存。


内容来自博主:墨肃

博客主页:http://www.gzwshop.xyz/

(如果觉得原创内容不错,记得点个在看哟~)

以上是关于高并发优化之页面缓存与URL缓存的主要内容,如果未能解决你的问题,请参考以下文章

nginx高并发优化之静态文件缓存配置

高并发之后端优化(PHP)

页面优化技术

高并发系统设计之缓存

一线大厂高并发Redis缓存架构

Java秒杀项目之页面优化