页面优化缓存技术+资源静态化+前后端分离?

版权声明:禁止转载 https://blog.csdn.net/qq_36505948/article/details/82620908

一、为什么要使用页面缓存技术?

系统都是逐渐演进的,一个系统在运行中必须是根据场景逐渐地提高优化性能。高并发就是对资源的节约的考验,这种考验除了更换优秀和先进的技术,优化架构,还在于从小处出发,对尽可能节约的资源进行节约。而在一个系统的数据访问中,系统的瓶颈往往是来自于数据库,我们要尽可能减少对数据库的访问!因此在不影响用户体验的情况下,对于一些静态或者变化不大的页面,我们使用缓存来减少对数据库的访问!


二、缓存技术的原理?

我们都知道在一个请求中,逻辑越复杂,调用,依赖,访问数据库的越多,耗时也就越长,响应时间也就越长,性能也就越差!因此降低逻辑复杂度,减低耦合,提高内聚,减少数据库访问,将频繁用到的变化不大的数据给缓存起来也就成为了提供性能的方法。


 1.页面缓存思路:

       首先我们需要明白,一个页面是从后端提高数据后,交给springMvc或者SpringBoot进行渲染,主要的页面消耗是在渲染这部分。因此我们需要在这之前进行拦截。

       当客户的请求到达后端时,先去redis中查询缓存,如果缓存中找不到,则进行数据库逻辑操作,然后渲染,存入缓存并返回给前端!如果在缓存中找到了则直接返回给前端。存储在Redis缓存中的页面需要设置超时时间,缓存的时间长度根据页面数据变化频繁程度适当调整!目前大多数页面缓存都是在60~120秒,少数几乎不变化的可以调整到5分钟!

 2.热点数据缓存思路:

所谓热点数据,就是指在某段时间内被频繁使用的对象数据。比如用户登录信息,用户在登录后,每次访问都会携带其cookie信息进入后端,当信息到达后端后,其cookie信息就是我们存在redis中的key值。在这一步我们会做两个操作;

       <1>当用户操作进来的时候,我们获取到Cookie值并在Redis中查找,找到用户信息则刷新用户的登录时间并允许用户通过,找不到用户信息则拒绝用户继续往下!,在后面的数据操作中,如果存在需要使用用户信息的操作,则去Redis中查找,如果存在则允许操作!

       <2>对于热点数据源,被高频访问的不缺分权限信息的热点数据,则设置全局缓存,定时更新则缓存数据,当有操作到此类的热点数据缓存则主动更新缓存中的信息,将用户拦截在数据之外!

       <3>当涉及到用户登录的热点数据被更新后,需要根据用户的token作为key值重新写入或者强制用户重新登录!

       <4>对于需要频繁更新的数据或写入数据的数据,比如点赞次数,在线人数,可以设置一个层级,在没有达到层级前写在缓存中,每次只更新缓存则可以,当到一定次数则写入数据库!


2.页面局部缓存:

       热点数据缓存,页面静态化进行ajax请求信息更新,此类信息一般都是比较频繁发生变化的,涉及的可能是需要保存在数据库的操作,类似表格信息,即时刷新的数据等!如果是属于查看类的并且前端大量请求,可以经由于后端监控,定时写入缓存!


三、缓存雪崩-数据穿透问题:

缓存雪崩:缓存雪崩是指因为数据未加载到缓存中,或者缓存同一时间大面积的失效,在某一时刻大量的缓存没有命中,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机!

1. 缓存穿透:查询一个数据库必然不存在的数据,那么缓存里面也没有。比如文章表中查询一个不存在的id,每次都会访问DB,如果有人恶意破坏,发送高频请求,那么很可能直接对DB造成影响。

解决办法:对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。或者对于查询为空的字段,设置一个默认值在缓存中,如果查询到则返回默认值! 或者使用具备特点的key值,如果不符合则经由于系统过滤掉,不进入缓存也不进入数据库,此做法可以降低一定的压力,但是解决不了根本的问题。

2.缓存失效:如果缓存集中在一段时间内失效,DB的压力凸显,DB负载急剧上升。这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

3.缓存预热:系统部署时,防止用户一瞬间访问数据库,负载过大,由开发人员主动将数据加载到缓存中!

单机---系统:手动刷新页面既可以了,或者定时缓存缓存

分布式系统:  分布式系统问题在于数据量非常大,缓存可能会导致数据库宕机!通过程序进行单个缓存加载!


四、Redis页面缓存实现

1.请求到来后,先调用根据key值去redis访问,找到则返回

2.SpringBoot的redis中找不到调用webConext()对象进行加载

1. 将Thyemleaf的thymeleafViewResolver给注入到Controller中
2. 进行页面渲染:
 WebContext  ctx=new 
 WebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap());
        html=thymeleafViewResolver.getTemplateEngine().process("页面名称无后缀",ctx);
3. 返回页面信息
================================================================================================
方法的返回以String对象,并且页面不可以使用ResController作为注解(以json返回),页面的reqestMapper里
设置:
 @RequestMapping(value = "/xxxx",produces ="text/html")//可能没有数据
 @ResponseBody


3.SpringMvc的redis中使用拦截器或者过滤器用ModelAndView渲染,拦截器的用法过于简单,自行百度,不做解释

       

猜你喜欢

转载自blog.csdn.net/qq_36505948/article/details/82620908
今日推荐