Spring Boot中集成Guava Cache或者Caffeine

一、在Spring Boot(1.x版本)中集成Guava Cache

  • 注意: Spring Boot 2.x+用戶:優先使用Caffeine,性能更優且維護活躍。

1. 添加依賴

pom.xml中添加Guava依賴:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version> <!-- 使用最新版本 -->
</dependency>

2. 啟用緩存支持

在啟動類上添加@EnableCaching注解:

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

3. 配置Guava緩存管理器

創建配置類定義CacheManager Bean:

@Configuration
public class CacheConfig {@Beanpublic CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager();cacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES) // 寫入10分鐘后過期.maximumSize(100) // 最大緩存數量.recordStats()); // 開啟統計信息return cacheManager;}
}

4. 使用緩存注解

在Service層使用@Cacheable@CacheEvict等注解:

@Service
public class UserService {// 緩存查詢結果,key為id@Cacheable(value = "USER_CACHE", key = "#id")public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}// 更新緩存@CachePut(value = "USER_CACHE", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 刪除緩存@CacheEvict(value = "USER_CACHE", key = "#id")public void deleteUser(Long id) {// 刪除用戶邏輯userRepository.deleteById(id);}}

5. 驗證緩存效果

編寫測試類或調用接口驗證緩存是否生效:

@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService userService;@Testpublic void testCache() {// 第一次調用,執行方法User user1 = userService.getUserById("123");// 第二次調用,從緩存獲取User user2 = userService.getUserById("123");// 驗證是否為同一對象(緩存生效)assertThat(user1).isSameAs(user2);}
}

高級配置

  • 多緩存配置:為不同緩存設置不同策略:

    @Bean
    public CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager();cacheManager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).maximumSize(500));cacheManager.setCacheBuilder("userCache", CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).maximumSize(100));return cacheManager;
    }
    
  • 刷新策略:使用refreshAfterWrite定時刷新(需配合LoadingCache):

    CacheBuilder.newBuilder().refreshAfterWrite(5, TimeUnit.MINUTES).build(CacheLoader.from(key -> loadData(key)));
    
  • 統計信息:通過recordStats()啟用統計,使用cache.getStatistics()獲取命中率等信息。

常見問題

  1. 緩存未生效

    • 確保啟動類有@EnableCaching
    • 檢查方法是否為public(注解在私有方法上無效)。
  2. 配置未應用

    • 確認CacheManager Bean正確注冊。
    • 檢查緩存名稱是否匹配@Cacheable(value = "cacheName")
  3. 內存溢出

    • 合理設置maximumSizeexpireAfterAccess/Write

通過以上步驟,即可在Spring Boot中高效使用Guava Cache實現本地緩存,提升應用性能。



二、Spring Boot 2.x及以上版本(推薦使用Caffeine)

在Spring Boot 2.x及以上版本中,Caffeine作為默認的本地緩存組件,取代了Guava Cache,提供了更高的性能和更靈活的配置。


1. 添加依賴

需引入spring-boot-starter-cachecaffeine依賴:

<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>3.1.8</version> <!-- 推薦使用最新版本 -->
</dependency>

2. 啟用緩存支持

在啟動類添加@EnableCaching注解:

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

3. 配置Caffeine緩存

方式一:通過配置文件

application.yml中定義全局緩存參數:

spring:cache:type: caffeinecaffeine:spec: maximumSize=500,expireAfterWrite=600s,initialCapacity=100cache-names: userCache, productCache  # 定義緩存名稱
  • 常用參數
    • maximumSize:最大緩存條目數
    • expireAfterWrite:寫入后過期時間
    • initialCapacity:初始容量。
方式二:通過Java Config類

為不同緩存設置獨立策略(推薦多緩存場景):

@Configuration
@EnableCaching
public class CacheConfig {public enum Caches {USER_CACHE(600, 1000),  // 有效期600秒,最大容量1000PRODUCT_CACHE(3600);private final int ttl;private final int maxSize;Caches(int ttl, int maxSize) {this.ttl = ttl;this.maxSize = maxSize;}public int getTtl() {return ttl;}public int getMaxSize() {return maxSize;}}@Beanpublic CacheManager cacheManager() {SimpleCacheManager manager = new SimpleCacheManager();List<CaffeineCache> caches = Arrays.stream(Caches.values()).map(c -> new CaffeineCache(c.name(), Caffeine.newBuilder().expireAfterWrite(c.getTtl(), TimeUnit.SECONDS).maximumSize(c.getMaxSize()).build())).collect(Collectors.toList());manager.setCaches(caches);return manager;}
}

此方式支持為每個緩存單獨配置過期時間和容量。


4. 使用緩存注解

在Service層通過注解操作緩存:

@Service
public class UserService {// 緩存查詢結果,key為id@Cacheable(value = "USER_CACHE", key = "#id")public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}// 更新緩存@CachePut(value = "USER_CACHE", key = "#user.id")public User updateUser(User user) {return userRepository.save(user);}// 刪除緩存@CacheEvict(value = "USER_CACHE", key = "#id")public void deleteUser(Long id) {userRepository.deleteById(id);}
}
  • 注解說明
    • @Cacheable:查詢時優先從緩存讀取
    • @CachePut:更新數據并刷新緩存
    • @CacheEvict:刪除數據時移除緩存。

5. 高級配置

刷新策略(RefreshAfterWrite)

需定義CacheLoader以支持自動刷新:

@Bean
public CacheLoader<Object, Object> cacheLoader() {return new CacheLoader<>() {@Overridepublic Object load(Object key) {return loadDataFromDB(key);  // 初始加載數據}@Overridepublic Object reload(Object key, Object oldValue) {return oldValue;  // 刷新時保留舊值,異步加載新值}};
}

配置文件中需添加refreshAfterWrite=5s,并關聯此Bean。

統計與監控

啟用統計功能:

Caffeine.newBuilder().recordStats().build();

通過cache.stats()獲取命中率、回收數量等指標。


6. 驗證緩存效果

通過測試類驗證緩存是否生效:

@SpringBootTest
public class CacheTest {@Autowiredprivate UserService userService;@Testpublic void testCache() {User user1 = userService.getUserById(1L);  // 首次查詢,存入緩存User user2 = userService.getUserById(1L);  // 二次查詢,命中緩存assertThat(user1).isSameAs(user2);}
}

常見問題

  1. 緩存未命中

    • 檢查方法是否為public(注解在私有方法無效)
    • 確認緩存名稱與配置一致。
  2. 配置沖突

    • 避免同時配置maximumSizemaximumWeight
    • expireAfterWrite優先級高于expireAfterAccess

通過以上步驟,可在Spring Boot 2.x中高效集成Caffeine,實現高性能本地緩存,適用于高頻訪問但更新較少的數據場景(如配置信息、靜態數據)。



三、Caffeine使用場景

Caffeine 作為高性能本地緩存庫,適用于多種需要快速數據訪問和高效內存管理的場景。以下是其主要使用場景及對應的技術優勢分析:


1. 高并發請求緩存

  • 場景描述:適用于高頻訪問的接口或熱點數據,例如用戶信息查詢、商品詳情展示等。Caffeine 通過無鎖并發設計和 Window TinyLFU 算法,顯著提升緩存命中率,減少數據庫壓力。
  • 技術優勢
    • 高性能:在高并發環境下,Caffeine 的吞吐量遠超 Guava Cache,其分段鎖機制避免了鎖競爭問題。
    • 高命中率:Window TinyLFU 算法結合 LRU 和 LFU 優點,有效保留高頻訪問數據,命中率比 Guava 提升 10%~20%。
  • 典型應用:Web 應用的 API 接口緩存,如電商平臺的商品詳情頁。

2. 數據庫查詢緩存

  • 場景描述:用于緩存頻繁查詢的數據庫結果,如用戶常用配置、熱門商品庫存等,減少重復數據庫訪問。
  • 技術優勢
    • 自動過期策略:支持 expireAfterWrite(寫入后過期)和 expireAfterAccess(訪問后過期),防止數據過時。
    • 內存管理:通過 maximumSize 限制緩存條目數,避免內存溢出,結合惰性刪除和定時清理機制優化內存使用。
  • 典型應用:用戶登錄信息緩存、商品庫存實時查詢緩存。

3. 復雜計算結果緩存

  • 場景描述:緩存計算密集型操作的結果,如圖像處理、大數據聚合分析等,避免重復計算消耗資源。
  • 技術優勢
    • 異步加載:通過 AsyncLoadingCache 異步加載數據,減少主線程阻塞,提升系統響應速度。
    • 刷新機制:使用 refreshAfterWrite 定時刷新緩存,保證數據更新后的及時性,同時保留舊數據直至新數據加載完成。
  • 典型應用:推薦系統的實時計算結果緩存、圖像處理后的縮略圖緩存。

4. 多級緩存架構(L1緩存)

  • 場景描述:在分布式系統中作為一級本地緩存(L1),結合 Redis(L2)和數據庫(L3)形成三級緩存,減少跨服務或跨節點的網絡延遲。
  • 技術優勢
    • 低延遲訪問:本地內存訪問速度極快,適合對延遲敏感的場景。
    • 靈活集成:通過 CacheLoaderWriter 接口,可無縫與 Redis 等外部緩存聯動,實現數據回源和同步。
  • 典型應用:秒殺系統的庫存緩存、分布式服務中的配置信息緩存。

5. 需要高靈活性和統計監控的場景

  • 場景描述:對緩存策略有定制化需求(如動態調整過期時間、監聽緩存事件)或需監控緩存命中率的場景。
  • 技術優勢
    • 靈活配置:支持基于大小、時間、引用等多種淘汰策略,并可自定義過期邏輯。
    • 統計功能:通過 recordStats() 啟用統計,獲取命中率、淘汰次數等指標,便于性能調優。
  • 典型應用:實時監控系統的緩存健康狀態、需要動態調整緩存策略的業務場景。

注意事項

  1. 非分布式場景:Caffeine 僅適用于本地緩存,跨節點數據需結合 Redis 等分布式緩存。
  2. 內存限制:需根據應用內存合理設置 maximumSize 或權重,避免 OOM 問題。
  3. 數據一致性:本地緩存可能導致多實例間數據不一致,需通過過期時間或事件通知機制解決。

總結

Caffeine 憑借其高性能、高命中率和靈活的配置,成為高并發、低延遲場景下的首選本地緩存庫。尤其適合作為一級緩存與 Redis 等組成多級緩存架構,或用于需要快速響應和復雜策略管理的業務場景。實際應用中需結合具體需求調整淘汰策略和內存配置,以最大化其優勢。

更多用法:

SpringBoot:第五篇 集成Guava(本地緩存+分布式緩存)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79139.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux工作臺文件操作命令全流程解析

全文目錄 1 確認當前工作路徑2 導航與目錄管理2.1 關鍵命令2.2 邏輯銜接 3 文件基礎操作3.1 創建 → 備份 → 重命名 → 清理3.2 文件查看和編輯3.3 文件鏈接3.4 文件diff 4 文件權限與所有權管理5 文件打包與歸檔6 參考文獻 寫在前面 shell是一種命令解釋器&#xff0c;它提供…

LeetCode第183題_從不訂購的客戶

LeetCode 第183題&#xff1a;從不訂購的客戶 題目描述 表: Customers ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | ---------------------- id 是該表的主鍵。 該表包含消費者的 id 和…

c語言的常用關鍵字

c語言的常用關鍵字 c語言的關鍵字表示數據類型的關鍵字autocharfloatdoubleintlongshortvoidsignedstruct、enum、unionunsigned 表示分支語句的關鍵字ifelseswitchbreakcasecontinuedefault 表示循環語句的關鍵字whiledoforgoto 用于修飾變量或函數的關鍵字constconst修飾變量…

MCU通用輸入輸出端口(GPIO)設計指南

在嵌入式系統開發中&#xff0c;MCU的GPIO接口是一個基礎但非常實用的功能模塊。GPIO全稱是通用輸入輸出端口&#xff0c;它讓MCU可以靈活地與外部設備進行交互。 GPIO的主要特點包括&#xff1a; 多功能性&#xff1a;每個引腳都可以單獨配置為輸入或輸出 可編程性&#xff…

STM32完整內存地址空間分配詳解

在STM32這類基于ARM Cortex-M的32位微控制器中&#xff0c;整個4GB的地址空間(從0x00000000到0xFFFFFFFF)有著非常系統化的分配方案&#xff0c;每個區域都有其特定的用途。下面我將詳細介紹這些地址區域的分配及其功能&#xff1a; STM32完整內存地址空間分配詳解(0x00000000…

實現水平垂直居中的多種方法

在前端開發中&#xff0c;元素的居中是一個常見但又經常讓人頭疼的問題。本文將全面總結各種CSS居中方法&#xff0c;特別是如何實現一個div的水平垂直居中。 為什么居中這么重要&#xff1f; 居中布局是現代網頁設計中最基礎也最重要的布局方式之一。無論是導航菜單、登錄框…

如何實現服務的自動擴縮容(Auto Scaling)

在云計算和分布式系統的時代,系統的彈性和適應性已成為企業構建高效IT基礎設施的核心需求。自動擴縮容(Auto Scaling)作為一種關鍵技術,旨在根據實時負載變化動態調整計算資源,以確保系統性能穩定,同時優化資源利用效率。簡單來說,自動擴縮容是指系統能夠根據預設規則或…

uniapp+vue3+ts 使用canvas實現安卓端、ios端及微信小程序端二維碼生成及下載

加粗樣式uniapp多端生成帶二維碼海報并保存至相冊的實現 在微信小程序開發中&#xff0c;我們常常會遇到生成帶有二維碼的海報并保存到手機相冊的需求&#xff0c;比如分享活動海報、產品宣傳海報等。今天就來和大家分享一下如何通過代碼實現這一功能。 準備工作 在開始之前&am…

架構師面試(三十八):注冊中心架構模式

題目 在微服務系統中&#xff0c;當服務達到一定數量時&#xff0c;通常需要引入【注冊中心】組件&#xff0c;以方便服務發現。 大家有沒有思考過&#xff0c;注冊中心存在的最根本的原因是什么呢&#xff1f;注冊中心在企業中的最佳實踐是怎樣的&#xff1f;注冊中心的服務…

Day.js和Moment.js對比,日期時間庫怎么選?

在JavaScript的日期處理庫中&#xff0c;Moment.js 和 Day.js 是兩個非常流行的選擇。本文將基于從npmtrends的數據&#xff0c;對這兩個庫進行詳細的對比分析。 Moment.js的重度使用者。凡是遇到時間和日期的操作&#xff0c;就把Moment.js引用上。 直到有天我發現加載的mome…

羅默如何用木星衛星“宇宙鐘表”測量光速?

一、17世紀的“宇宙級實驗” 1676年&#xff0c;丹麥天文學家奧勒羅默&#xff08;Ole Rmer&#xff09;在巴黎天文臺做出驚人發現&#xff1a; 木星衛星的“遲到早退”現象&#xff0c;竟能揭示光速的秘密&#xff01; 通過觀察木衛一&#xff08;Io&#xff09;的軌道周期變…

deepseek 技巧整理

1、導出word 和excel 功能&#xff0c;在使用以下提示詞。 請幫我列出減肥期間可以吃的水果&#xff0c;并分析該水果含有的營養元素&#xff0c;以表格的形式星現。1.要以html的方式輸出 2.要可以直接運行 3.頁面要提供可以直接下載word和excel功能

思考軟件框架

數據庫是達夢數據庫 假定里面有40張表&#xff0c;軟件的業務邏輯比較復雜。 當然&#xff0c;依然是對數據庫中數據的增&#xff0c;刪&#xff0c;改&#xff0c;查&#xff0c;組合&#xff0c;顯示。 但是也涉及到多種軟件&#xff0c;多臺設備之間的通信。 我們可以使用…

探索 Disruptor:高性能并發框架的奧秘

在當今的軟件開發領域&#xff0c;處理高并發場景是一項極具挑戰性的任務。傳統的并發解決方案&#xff0c;如基于鎖的隊列&#xff0c;往往在高負載下表現出性能瓶頸。而 Disruptor 作為一個高性能的并發框架&#xff0c;憑借其獨特的設計和先進的技術&#xff0c;在處理海量數…

前端面經-VUE3篇--vue3基礎知識(一)插值表達式、ref、reactive

一、計算屬性(computed) 計算屬性&#xff08;Computed Properties&#xff09;是 Vue 中一種特殊的響應式數據&#xff0c;它能基于已有的響應式數據動態計算出新的數據。 計算屬性有以下特性&#xff1a; 自動緩存&#xff1a;只有當它依賴的響應式數據發生變化時&#xff…

數據結構6 · BinaryTree二叉樹模板

代碼函數功能順序如下&#xff1a; 1&#xff1a;destroy&#xff1a;遞歸刪除樹 2&#xff1a;copy&#xff1a;復制二叉樹 3&#xff1a;preOrder&#xff1a;遞歸前序遍歷 4&#xff1a;inOrder&#xff1a;遞歸中序遍歷 5&#xff1a;postOrder&#xff1a;遞歸后續遍…

C++/SDL進階游戲開發 —— 雙人塔防游戲(代號:村莊保衛戰 13)

&#x1f381;個人主頁&#xff1a;工藤新一 &#x1f50d;系列專欄&#xff1a;C面向對象&#xff08;類和對象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;終會照亮我前方的路 &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏?文章 文章目錄 十…

強化學習之基于無模型的算法之時序差分法

2、時序差分法(TD) 核心思想 TD 方法通過 引導值估計來學習最優策略。它利用當前的估計值和下一個時間步的信息來更新價值函數&#xff0c; 這種方法被稱為“引導”&#xff08;bootstrapping&#xff09;。而不需要像蒙特卡羅方法那樣等待一個完整的 episode 結束才進行更新&…

AE/PR模板 100個現代文字標題動態排版效果動畫 Motion Titles

Motion Titles是一個令人驚艷的AE/PR模板&#xff0c;提供了100個現代文字標題的動態排版效果動畫。這些動畫效果能夠為你的項目增添視覺沖擊力和專業感&#xff0c;為文字標題注入活力和動感。該模板適用于Adobe After Effects CC或更高版本以及Adobe Premiere Pro 2020或更高…

【AI提示詞】二八法則專家

提示說明 精通二八法則&#xff08;帕累托法則&#xff09;的廣泛應用&#xff0c;擅長將其應用于商業、管理、個人發展等領域&#xff0c;深入理解其在不同場景中的具體表現和實際意義。 提示詞 # Role: 二八法則專家## Profile - language: 中文 - description: 精通二八法…