springboot-No11-1:页面优化技术Thymeleaf简单实践 之缓存使用

常见的页面优化技术

页面的优化技术分为:缓存和,页面静态化,静态资源优化,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 );

扫描二维码关注公众号,回复: 1033764 查看本文章


渲染模板

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的负载




猜你喜欢

转载自blog.csdn.net/fk002008/article/details/80209128
今日推荐