SpringBoot項目開發(二十):Caffeine本地緩存

爲什麼需要本地緩存?在系統中,有些數據,訪問十分頻繁(例如數據字典數據、國家標準行政區域數據),往往把這些數據放入分佈式緩存中,但爲了減少網絡傳輸,加快響應速度,緩存分佈式緩存讀壓力,會把這些數據緩存到本地JVM中,大多是先取本地緩存中,再取分佈式緩存中的數據

而Caffeine是一個高性能Java 緩存庫,使用Java8對Guava緩存重寫版本,在Spring Boot 2.0中將取代Guava。
使用spring.cache.cache-names屬性可以在啓動時創建緩存
例如,以下application配置創建一個foo和bar緩存,最大數量爲500,存活時間爲10分鐘

spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

還有一種代碼實現方式,我在項目中就是使用代碼方式,如何使用,請往下看…

1.引入依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.6.2</version>
</dependency>
2.添加一個CaffeineConfig配置類,開啓緩存@EnableCaching
@Configuration
@EnableCaching //開啓緩存
public class CaffeineConfig {
    public static final int DEFAULT_MAXSIZE = 10000;
    public static final int DEFAULT_TTL = 600;
    /**
     * 定義cache名稱、超時時長(秒)、最大容量
     * 每個cache缺省:10秒超時、最多緩存50000條數據,需要修改可以在構造方法的參數中指定。
     */
    public enum Caches{
        getUserById(600),          //有效期600秒
        listCustomers(7200,1000),  //有效期2個小時 , 最大容量1000
        ;
        Caches() {
        }
        Caches(int ttl) {
            this.ttl = ttl;
        }
        Caches(int ttl, int maxSize) {
            this.ttl = ttl;
            this.maxSize = maxSize;
        }
        private int maxSize=DEFAULT_MAXSIZE;    //最大數量
        private int ttl=DEFAULT_TTL;        //過期時間(秒)
        public int getMaxSize() {
            return maxSize;
        }
        public int getTtl() {
            return ttl;
        }
    }

    /**
     * 創建基於Caffeine的Cache Manager
     * @return
     */
    @Bean
    @Primary
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        ArrayList<CaffeineCache> caches = new ArrayList<CaffeineCache>();
        for(Caches c : Caches.values()){
            caches.add(new CaffeineCache(c.name(),
                    Caffeine.newBuilder().recordStats()
                            .expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
                            .maximumSize(c.getMaxSize())
                            .build())
            );
        }
        cacheManager.setCaches(caches);
        return cacheManager;
    }
}
3.創建一個控制器,使用本地緩存,注意@Cacheable,value與上面配置的值對應,key爲參數,sync=true表示同步,多個請求會被阻塞
@RestController
@RequestMapping("cache")
public class CacheController {

    @RequestMapping("listCustomers")
    @Cacheable( value = "listCustomers" , key = "#length", sync = true)
    public List<Customer> listCustomers(Long length){
        List<Customer> customers = new ArrayList<>();
        for(int i=1; i <= length ; i ++){
            Customer customer = new Customer(i, "zhuyu"+i, 20 + i, false);
            customers.add(customer);
        }
        return customers;
    }
}
4.啓動項目,訪問上面的方法,效果如下,第一次處理時間爲 110ms ,再刷新幾次頁面只要 1ms,說明後面的請求從本地緩存中獲取數據,並返回了

這裏寫圖片描述
這裏寫圖片描述

使用本地緩存可以加快頁面響應速度,緩存分佈式緩存讀壓力,大量、高併發請求的網站比較適用

Caffeine配置說明:
initialCapacity=[integer]: 初始的緩存空間大小
maximumSize=[long]: 緩存的最大條數
maximumWeight=[long]: 緩存的最大權重
expireAfterAccess=[duration]: 最後一次寫入或訪問後經過固定時間過期
expireAfterWrite=[duration]: 最後一次寫入後經過固定時間過期
refreshAfterWrite=[duration]: 創建緩存或者最近一次更新緩存後經過固定的時間間隔,刷新緩存
recordStats:開發統計功能

注意:
expireAfterWrite和expireAfterAccess同時存在時,以expireAfterWrite爲準。
maximumSize和maximumWeight不可以同時使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章