• 周二. 9月 27th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

springboot使用缓存(一)

admin

11月 28, 2021

一、概述

在实际项目中,我们经常遇到这种场景,一些数据更新频率不大,但是访问频繁,而且访问耗时比较长,就比如我的有些接口最长需要7秒才能返回。

虽然这个是有原因的,但这个时长依然是不能忍受的。

这种情况下,在springboot中使用缓存成为一种简单有效的方式。

说到缓存,就需要先确定,缓存到哪里,如果是单节点服务,推荐使用ehcache,如果是分布式服务,首选redis

这里以ehcache为例,描述下缓存的基本使用流程。

二、依赖

开启缓存需要依赖springboot的cache模块和ehcache,下面引入相关依赖

  <!--缓存-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.4.4</version>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>

三、开启缓存

在入口类添加注解开启缓存

@EnableCaching
@EnableSwagger2
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

四、缓存配置

ehcache是两级缓存,第一级在内存,内存放不下就写入磁盘,项目中需要对一些基本配置项做配置,在resources目录下加入ehcache.xml文件,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="defaultCache">
    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir/ehcache"/>
    <!--
            maxEntriesLocalHeap:堆内存中最大缓存对象数
            eternal:对象是否永久有效,一但设置了,timeout将不起作用
            overflowToDisk:当缓存达到maxElementsInMemory值是,是否允许溢出到磁盘
            timeToIdleSeconds:当缓存闲置n秒后销毁
            timeToLiveSeconds:当缓存存活n秒后销毁
            maxEntriesLocalDisk:硬盘最大缓存个数
            diskPersistent:磁盘缓存在JVM重新启动时是否保持
         -->
    <!-- 默认缓存 -->
    <defaultCache
            maxEntriesLocalHeap="10000"
            eternal="false"
            timeToIdleSeconds="600"
            timeToLiveSeconds="600"
            maxEntriesLocalDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <!-- fill-in缓存 -->
    <cache name="fillIn"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="600"
           timeToLiveSeconds="600"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"/>

</ehcache>

五、java配置引用XML

import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;


@Configuration
@EnableCaching
public class CachingConfig {

    @Bean
    public EhCacheCacheManager cacheManager(CacheManager cm) {
        return new EhCacheCacheManager(cm);
    }

    @Bean
    public EhCacheManagerFactoryBean ehcache() {
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        return cacheManagerFactoryBean;
    }
}

六、缓存应用

哪些方法需要缓存呢,当然是哪些耗时最久的方法,比如我的某个service实现类中有个数据库查询方法queryData,开启缓存就需要如下配置

    @Cacheable(value = "fillIn")
    @Override
    public List<Map<String, Object>> queryData(String tbName) {
        List<String> columns = columnsDao.selectColumns(tbName);
        List<Map<String, Object>> maps = dataDao.selectAll(tbName, columns);
        return maps;
    }

经过测试,第一次访问时长不变,之后接口的返回时长从数秒降低到数毫秒,效率提升了1000倍,真是太香了!

实践中发现有些无参数的方法加了缓存之后,没有生效,这种情况需要手动指定缓存的key

下面是一些官方指定的可以用作key的变量,可以直接拿来用

发表回复

您的电子邮箱地址不会被公开。