当前位置: 首页 > news >正文

缓存优化(SpringCache、XXL-JOB)

目录

首页优化

一、SpringCache:

1.@EnableCaching

2.@CachePut

3.@Cacheable

4.@CacheEvict

5.如何设置缓存时间

二、正式优化

准备工作:

开通区域列表:

查询区域时添加缓存:

启用、禁用区域时清理缓存:

首页服务列表:

查询首页服务列表添加缓存:

禁用区域时删除缓存:

三、XXL-JOB

1)编写代码端

2)配置控制端

定时更新缓存:

四、实战


首页优化

我们一般把小程序、网站、app的首页称为系统的门户,门户有下面特点:

  1. 门户的信息是动态的,但是更新频率不会非常高

  2. 门户作为系统的入口,访问频率会非常高

针对系统中访问频率很高的页面,我们常见的优化方案如下:

  1. 将页面做页面静态化处理

  2. 如果静态化之后依旧无法满足需求,可以将静态资源转移到CDN服务器

  3. 页面上变动的内容可以异步请求后端服务器获取数据,后端可以添加缓存来减轻数据库的压力

  4. 数据库方面可以通过合理的存储引擎选择、表字段设计、索引设计等进一步提高查询效率

一、SpringCache:

目前业界最主流的缓存技术就是Redis,而Java操作Redis目前有两种主流方案:

  • RedisTemplate:Spring提供的一个对象,内置了大量操作redis的方法,使用起来比较灵活

  • SpringCache:Spring提供的一套注解,可以基于方法级别对redis进行操作,使用起来非常简单

两种方式各有自己的优缺点,推荐大家以SpringCache为主,特殊情况下再采用RedisTemplate

SpringCache常用的注解有下面几个:

  • @EnableCaching:标注在启动类上,用来开启缓存注解功能

  • @Cacheable:主要标注在查询方法上,表示先从缓存中查询数据,如果有直接返回,如果没有再从数据库查询,返回的同时保存到缓存中一份

  • @CacheEvict:主要标注在新增、修改、删除方法上,用于将一条或多条数据从缓存中删除

  • @CachePut:用于更新缓存,它可以将方法的返回值放到缓存中

SpringCache支持多种缓存提供者,如Redis、EhCache、Caffeine等,我们可以自由切换他们

甚至我们可以不去提供任何的缓存服务器,SpringCache依旧可以使用,他会使用内存做为缓存提供者

1.@EnableCaching

@EnableCaching注解标注在启动类或者配置类上,用于开启基于注解的缓存功能

2.@CachePut

@CachePut:用于将方法的返回值放到缓存中,支持两个属性:

  • value: 缓存模块名称,每个模块下可以有很多key

  • key: 缓存的唯一标识,要注意的是它仅仅在一个value下保持唯一 也就是说value+key才能保证全局唯一

3.@Cacheable

@Cacheable:主要标注在查询方法上,表示先从缓存中查询数据,如果有直接返回,如果没有再从数据库查询,返回的同时保存到缓存中一份

4.@CacheEvict

@CacheEvict:用于删除缓存,将一条或多条数据从缓存中删除

5.如何设置缓存时间

默认情况下,使用@Cacheable或者@CachePut放入缓存中的数据都是永久生效的,如何设置缓存的过期时间呢?

在@Cacheable、@CachePut注解中有一个属性为cacheManager,表示缓存管理器,通过它可以设置缓存过期时间

  1. 创建一个配置类,然后向容器中放入一个RedisCacheManager

    @Configuration
    public class SpringCacheConfig {@Beanpublic RedisCacheManager cacheManager30Minutes(RedisConnectionFactory connectionFactory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(30 * 60L));return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();}
    }
  2. 在@Cacheable注解中使用cacheManager引用刚刚放入容器中的缓存管理器

        @Cacheable(value = "userCache",key = "#id",cacheManager = "cacheManager30Minutes")@GetMapping("/user/{id}")public User findById(@PathVariable Long id){return userMapper.getById(id);}

二、正式优化

接下来,我们为小程序首页添加缓存功能,需要添加的位置如下:

  1. 首页服务列表

  2. 热门服务列表(实战)

  3. 开通区域列表

准备工作:

  1. 在jzo2o-foundations工程的pom.xml中引入jzo2o-redis的依赖,它内置了大量Redis的配置;
    该依赖包含了redis、SpringCache的依赖

    <dependency><groupId>com.jzo2o</groupId><artifactId>jzo2o-redis</artifactId>
    </dependency>
  2. 在jzo2o-foundations工程的bootstrap.yml中引入redis的配置文件

  3. 在nacos配置shared-redis-cluster.yaml,开发环境使用redis单机环境

开通区域列表:

查询区域时添加缓存:

在查询开通区域列表的时候,先从缓存查询,如果有直接返回,没有再从数据库查询并存入缓存,这可以使用@Cacheable实现

找到查询开通区域列表的请求路径: /foundations/consumer/region/activeRegionList

定位到com.jzo2o.foundations.controller.consumer.RegionController.activeRegionList()

然后找到service方法添加如下注解(注意这里是在实现类):

启用、禁用区域时清理缓存:

当启用、禁用一个区域后,原来缓存的区域列表就不对了,需要删除它,可以使用@CacheEvict注解。找到启用、禁用区域的代码,修改如下:

//区域启用后,当前启用区域列表就发生变更,需要清空已启用的区域列表
@CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'")
@Override
public void active(Long id) {//.......
}
//禁用区域后, 当前启用区域列表就发生变更,需要清空已启用的区域列表
@CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'")
@Override
public void deactivate(Long id) {//...
}

首页服务列表:

当我们想设置多个@Cacheable、@CacheEvict注解时会发现不能重复注解,但是我们的业务又需要重复注解,这个时候就需要用到@Caching注解来一次性声明多个注解达成业务目标,比如接下来的两段代码:

查询首页服务列表添加缓存:

根据前端的请求路径定位到查询服务列表的方法,com.jzo2o.foundations.service.impl.ServeServiceImpl.firstPageServeList()

需要在此方法上添加一个@Cacheable注解,表示先从缓存查询,没有再从数据库查

但是我们这里做个优化,采用一个新的注解@Caching来实现,它可以将多个@Cacheable、@CacheEvict注解组合使用

@Caching(cacheable = {//返回数据为空,则缓存空值30分钟,这样可以避免缓存穿透@Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key ="#regionId" ,unless ="#result.size() > 0",cacheManager = RedisConstants.CacheManager.THIRTY_MINUTES),//返回值不为空,则永久缓存数据@Cacheable(value = RedisConstants.CacheName.SERVE_ICON, key ="#regionId" ,unless ="#result.size() == 0",cacheManager = RedisConstants.CacheManager.FOREVER)}
)
@Override
public List<ServeCategoryResDTO> firstPageServeList(Long regionId) {//...
}

在Cacheable注解中有两个属性可以指定条件进行缓存

  • condition:对方法参数进行判断,只缓存符合条件的

  • unless:对方法返回结果进行判断,只缓存不符合条件的

禁用区域时删除缓存:

当我们禁用一个区域的时候,除了删除开通区域列表,还需要删除首页服务列表、热门服务列表、服务分类列表、服务详情等

找到禁用区域代码(刚才上面那个),添加删除首页服务列表缓存的代码,如下:

@Caching(evict = {//删除开通区域列表@CacheEvict(value = RedisConstants.CacheName.JZ_CACHE, key = "'ACTIVE_REGIONS'"),//删除首页服务列表@CacheEvict(value = RedisConstants.CacheName.SERVE_ICON,key = "#id")}
)
@Override
public void deactivate(Long id) {//....
}

三、XXL-JOB

我们现在已经实现了在一些操作时添加、删除缓存,但是为了程序更具备健壮性,需要使用定时任务更新缓存

可以用来做定时任务的框架有很多,常见的有:

  • SpringTask:单节点定时任务框架,只能用在单体项目中

  • XXL-JOB:分布式定时任务框架,适用于单体项目和分布式项目

XXL-JOB是一个轻量级分布式任务调度平台,它的主要角色有两个:

  • 调度中心:负责按照调度配置发出调度请求,主要职责为执行器管理、任务管理、监控运维、日志管理等

  • 任务执行器:负责接收调度请求并执行任务逻辑;主要职责是执行任务、执行结果上报、日志服务等

XXL-JOB的使用主要就是分为两步:

  1. 在代码端编写定时任务要执行的代码

  2. 在控制端配置代码的执行时机和其他信息

1)编写代码端

  1. 导入准备好的演示工程

  2. 准备好要执行的任务代码

  3. 修改配置文件

      2)配置控制端

      1. 配置执行器:在任务调度中心,点击进入"执行器管理"界面,添加执行器

          AppName:执行器的唯一标识,不能重复

          名称:执行的名称

          注册方式:调度中心获取执行器地址的方式

          机器地址:执行器的地址,当注册方式为手动时生效

        1. 配置任务:在调度中心新建任务,在任务管理->新建,填写以下内容

            执行器:任务对应的执行器名称

            调度类型:cron表达式,配置后面的表达式内容一起使用

            JobHandler:任务执行器名称,需要对应到代码对任务代码上@XxlJob注解对应的名称

          运行模式:BEAN模式:任务以JobHandler方式维护在执行器端;需要结合 "JobHandler" 属性使用
          JobHandler:运行模式为 "BEAN模式" 时生效,对应执行器中JobHandler类“@XxlJob”注解的value值
          执行参数:任务执行所需的参数

        2. 重启微服务,然后启动任务(或者选择执行一次),观察效果

            定时更新缓存:

            1.我们已经在虚拟机当中安装好了xxl-job的容器,只需要访问以下地址即可:http://192.168.101.68:8088/xxl-job-admin/;输入账号密码后登入:

            2.接下来在foundations服务中引入依赖:

            <dependency><groupId>com.jzo2o</groupId><artifactId>jzo2o-xxl-job</artifactId>
            </dependency>

            3.然后在bootstrap.yml文件下进行配置(具体配置被配置在了nacos当中):

            4.编写任务代码:
            编写代码,先删除开通区域、服务列表的缓存,再查询开通区域、服务列表进行缓存

            package com.jzo2o.foundations.handler;import com.jzo2o.api.foundations.dto.response.RegionSimpleResDTO;
            import com.jzo2o.foundations.constants.RedisConstants;
            import com.jzo2o.foundations.service.IRegionService;
            import com.jzo2o.foundations.service.IServeService;
            import com.xxl.job.core.handler.annotation.XxlJob;
            import lombok.extern.slf4j.Slf4j;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.data.redis.core.RedisTemplate;
            import org.springframework.stereotype.Component;import java.util.List;//缓存同步类
            @Component
            @Slf4j
            public class SpringCacheSyncHandler {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate IRegionService regionService;@Autowiredprivate IServeService serveService;@XxlJob("activeRegionCacheSync")public void activeRegionCacheSync() {log.info("=============开始更新开通区域列表缓存============");//1. 使用redisTemplate删除当前缓存中开通区域列表redisTemplate.delete("JZ_CACHE::ACTIVE_REGIONS");//2. 重新将开通区域列表添加到缓存List<RegionSimpleResDTO> regionSimpleResDTOS= regionService.queryActiveRegionListCache();log.info("=============开始更新首页服务列表缓存============");//3. 查询所有开通区域, 然后进行遍历for (RegionSimpleResDTO regionSimpleResDTO : regionSimpleResDTOS) {//获取到每个开通区域的idLong id = regionSimpleResDTO.getId();//根据区域id删除缓存数据redisTemplate.delete(RedisConstants.CacheName.SERVE_ICON + "::" + id);//重新查询,放入缓存serveService.firstPageServeList(id);}}
            }

            5.在调度中心配置任务:
            进入任务管理,新增任务:

            四、实战

            在当前代码的基础上,按照下面要求,完成热门服务的缓存优化

            1.找到ServeServiceImpl实体类下hotServeList方法并添加注解:

            2.找到RegionServiceImpl下的deactivate(区域禁用)方法添加如下注解:

            3.在定时任务代码中添加下图标识部分:

            http://www.dtcms.com/a/598950.html

            相关文章:

          1. 网站建设长期待摊费用个人网站的留言板怎么做
          2. 优惠劵网站怎么做srm系统
          3. Hugging Face Gated 模型下载全攻略:解决 401/403 和访问受限问题
          4. 建筑行业网站模板ajax实现wordpress导航栏
          5. 网站建设服务 杭州甜品店网页模板html
          6. 状态机的实现方法--C语言版本
          7. 网站做app开发有梦商城公司网站
          8. 网站开发系统毕业综合实践报告电子版个人简历模板
          9. 线代强化NO5|矩阵的运算法则|分块矩阵|逆矩阵|伴随矩阵|初等矩阵
          10. 最新域名网站查询网站背景大小
          11. 服装网站建设发展状况wordpress数据库访问慢
          12. 大同市住房城乡建设网站扬州网站建设 天维
          13. nat123做网站 查封编写网站的软件
          14. 天津房地产网站建设福建联美建设集团有限公司网站
          15. 简述网站建设有哪些步骤有什么网站可以做推广
          16. C语言进阶:位操作
          17. 建站网站苏州wordpress架设系统
          18. wordpress短代码返回html石家庄网站seo优化
          19. python合适做网站吗网站建设与维护面试
          20. 什么是Hinge损失函数
          21. 网站设计的趋势百度双站和响应式网站的区别
          22. usrsctp之cookie
          23. CC防护:抵御应用层攻击的精确防线
          24. 如何自己制作链接内容泰安网站建设优化
          25. 芜湖哪里做网站亚马逊雨林的资料
          26. Manus高精度动捕数据手套,Metagloves Pro对比Quantum Metagloves:谁是你的灵巧手研发最佳选择?
          27. 佛山网站建设3lue3lue修改图片网站
          28. 【开题答辩实录分享】以《中医古籍管理系统》为例进行答辩实录分享
          29. 做网站时如何给文字做超链接网络服务提供者知道网络用户利用其网络服务
          30. [Windows] 火绒弹窗拦截6.0.8.0、5.0.78.2-2025.11.05.1绿色独立版