亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Spring Boot 緩存應用場景

1. 前言

緩存是性能提升的大殺器!

要知道,內存的讀寫速度是硬盤的幾十倍到上百倍。緩存實際上就是利用內存的高速讀寫特性,提高熱點數據的操作速度。

Spring Boot 中使用緩存非常簡單,并且支持多種緩存實現。

本篇介紹比較常用的幾種緩存實現方式,及其對應的應用場景。

2. Spring Boot 默認緩存

Spring Boot 默認緩存是基于 ConcurrenMapCacheManager 緩存管理器實現的,從這個類名就能發現它本質上應該是一個 Map 集合容器。

ConcurrenMapCacheManager 結構比較簡單,一般用于比較輕量級的緩存使用場景。也就是緩存的數據量比較小,緩存操作不是特別頻繁的場景。

接下來就具體演示下, Spring Boot 默認緩存實現過程。

2.1 使用 Spring Initializr 創建項目

Spring Boot 版本選擇 2.2.5 ,Group 為 com.imooc , Artifact 為 spring-boot-cache ,生成項目后導入 Eclipse 開發環境。

2.2 引入項目依賴

引入 Web 項目依賴和緩存依賴。

實例:

		<!-- Web 依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 緩存依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

2.3 開啟緩存

在啟動類上添加注解 @EnableCaching 開啟緩存功能。

實例:


@SpringBootApplication
@EnableCaching // 開啟緩存
public class SpringBootCacheApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringBootCacheApplication.class, args);
	}
}

2.4 定義服務層方法

正常服務層方法會調用數據訪問層方法訪問數據庫,此處我們只需要演示緩存的作用,所以打印日志代替數據庫訪問方法。

實例:

/**
 * 商品服務類
 */
@Service
@CacheConfig(cacheNames = "GoodsCache")
public class GoodsService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * 按id獲取商品信息
	 */
	@Cacheable
	public GoodsDo getById(Long id) {
		logger.info("getById({})", id);
		GoodsDo goods = new GoodsDo();
		goods.setId(id);
		goods.setName("goods-" + id);
		return goods;
	}

	/**
	 * 刪除商品
	 */
	@CacheEvict(key = "#id")
	public void remove(Long id) {
		logger.info("remove({})", id);
	}

	/**
	 * 編輯商品信息
	 */
	@CachePut(key = "#goods.id")
	public GoodsDo edit(GoodsDo goods) {
		logger.info("edit id:{}", goods.getId());
		return goods;
	}
}

對于使用緩存的 GoodsService 服務類,我們需要具體解釋下:

  1. @CacheConfig 注解用于指定本類中方法使用的緩存名稱,該類使用的緩存名稱為 GoodsCache ,與其他緩存區域是隔離的。
  2. @Cacheable 用于開啟方法緩存,緩存的鍵是方法的參數,緩存的值是方法的返回值。如果多次調用該方法時參數 id 值相同,則第一次會執行方法體,并將返回值放入緩存;后續方法不會再執行方法體,直接將緩存的值返回。
  3. @CachePut 可以更新緩存,key = "#id" 表示采用參數中的 id 屬性作為鍵。當緩存中該鍵的值不存在時,則將返回值放入緩存;當緩存中該鍵的值已存在時,會更新緩存的內容。
  4. @CacheEvict 可以移除緩存,當調用該方法時,會移除 goods 中 id 屬性對應的緩存內容。

2.5 測試

為了充分理解緩存的含義,我們通過測試類發起測試。

實例:

@SpringBootTest
class SpringBootCacheApplicationTests {
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private CacheManager cacheManager;

	@Autowired
	private GoodsService goodsService;

	// 顯示當前使用的緩存管理器類型
	@Test
	void showCacheManager() {
		// 輸出:org.springframework.cache.concurrent.ConcurrentMapCacheManager
		logger.info(cacheManager.getClass().toString());
	}

	// 緩存測試
	@Test
	void cacheTest() {
		// 第一次執行,沒有緩存,執行方法體
		goodsService.getById(1L);
		// 再次執行,直接取出緩存,不執行方法體
		goodsService.getById(1L);
		// 移除緩存
		goodsService.remove(1L);
		// 再次執行,已經沒有對應緩存,所以執行方法體
		GoodsDo oldGoods = goodsService.getById(1L);
		// 打印緩存內容
		logger.info("old goods id:{} name:{}", oldGoods.getId(), oldGoods.getName());
		// 更新緩存
		GoodsDo temp = new GoodsDo();
		temp.setId(1L);
		temp.setName("新的商品");
		goodsService.edit(temp);
		// 查詢并打印已更新的緩存內容
		GoodsDo newGoods = goodsService.getById(1L);
		logger.info("new goods id:{} name:{}", newGoods.getId(), newGoods.getName());
	}
}

我們查看下控制臺輸出如下,驗證了我們設計的緩存機制。

圖片描述

使用 Spring Boot 默認緩存時控制臺輸出內容

3. 使用 Ehcache 緩存

Spring Boot 默認的緩存實現比較簡單,功能也十分有限。如果是企業級的中大型應用,需要尋求更加穩定、可靠的緩存框架。

Ehcache 是 Java 編程領域非常著名的緩存框架,具備兩級緩存數據——內存和磁盤,因此不必擔心內存容量問題。另外 Ehcache 緩存的數據會在 JVM 重啟時自動加載,不必擔心斷電丟失緩存的問題。

總之 Ehcache 的功能完整性和運行穩定性遠遠強于 Spring Boot 默認的緩存實現方式,而且 Spring Boot 使用 Ehcache 非常便捷,接下來我們就來實現下。

3.1 添加 Ehcache 依賴

我們在 spring-boot-cache 項目的基礎上添加 Ehcache 依賴。

實例:

		<!-- Ehcache 依賴 -->
		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
		</dependency>
		<!-- cache-api 依賴 -->
		<dependency>
			<groupId>javax.cache</groupId>
			<artifactId>cache-api</artifactId>
		</dependency>

3.2 添加 Ehcache 配置文件

首先在 application.properties 中指定配置文件的位置。

實例:

spring.cache.jcache.config=classpath:ehcache.xml
spring.cache.type=jcache

然后在 resource 文件夾中添加 ehcache.xml 配置文件,內容如下:

實例:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
	xmlns='http://www.ehcache.org/v3'
	xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
	<!-- 持久化路徑 -->
	<persistence directory="C://ehcache" />
	<!--緩存模板 -->
	<cache-template name="CacheTemplate">
		<expiry>
			<!--存活時間 -->
			<tti>60</tti>
		</expiry>
		<resources>
			<!--堆空間 -->
			<heap unit="entries">2000</heap>
			<!-- 堆外空間 -->
			<offheap unit="MB">500</offheap>
		</resources>
	</cache-template>

	<!--緩存對象 -->
	<cache alias="GoodsCache" uses-template="CacheTemplate">
	</cache>
</config>

Tips:Ehcache 的配置比較復雜,此處只是給出簡單的示例,感興趣的同學可以查閱更多資料。

3.3 測試

由于之前已經在啟動類添加 @EnableCaching ,我們再次運行測試類,輸出結果如下。

圖片描述

使用 Ehcache 時控制臺輸出內容

注意控制臺出現了 EhcacheManager 的字樣,說明我們此時使用的緩存是 Ehcache 。

4. 使用 Redis 緩存

Ehcache 依然是 Java 進程內的緩存框架,受限于 JVM 整體的內存分配策略。

如果是大型系統,緩存的數據量特別大,且性能要求很高,可以考慮直接使用 Redis 作為緩存。

Redis 可以采用單機、主備、集群等模式,視乎具體項目需求決定即可。目前各大云計算廠商均提供商用版的 Redis 緩存服務,性能卓越且接入簡單快速。

本節簡單地演示 Spring Boot 中使用 Redis 單機緩存的方法,真實生產環境中建議至少使用主備類型的 Redis 實例。

圖片描述

華為云提供的緩存服務

4.1 修改緩存依賴

因為需要使用 Redis 緩存,所以將引入的依賴項修改如下:

實例:

		<!-- Web 依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- 緩存依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<!-- Redis 相關依賴 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

4.2 修改緩存配置

修改 application.properties 配置文件,將 Redis 配置及緩存配置設置如下:

實例:

# 過期時間
spring.cache.redis.time-to-live=6000s

# Redis庫的編號
spring.redis.database=0
# Redis實例地址
spring.redis.host=127.0.0.1
# Redis實例端口號,默認6379
spring.redis.port=6379
# Redis登錄密碼
spring.redis.password=Easy@0122
# Redis連接池最大連接數
spring.redis.jedis.pool.max-active=10
# Redis連接池最大空閑連接數
spring.redis.jedis.pool.max-idle=10
# Redis連接池最小空閑連接數
spring.redis.jedis.pool.min-idle=0

4.3 測試

由于之前已經通過注解 @EnableCaching 開啟了緩存功能,此時我們直接運行測試類進行測試,輸出結果如下:

圖片描述

使用 Redis 緩存時控制臺輸出內容

從上圖輸出結果可以看出,已經成功使用了 Redis 緩存管理器。

另外我們可以直接使用 Redis 客戶端查看生成的緩存信息,如下圖已經有名為 GoodsCache::1 的緩存鍵存在了。

圖片描述

Redis 客戶端查看緩存信息

5. 小結

Spring Boot 支持多種緩存實現方式,可以根據項目需求靈活選擇。

  • 緩存數據量較小的項目,可以使用 Spring Boot 默認緩存。
  • 緩存數據量較大的項目,可以考慮使用 Ehcache 緩存框架。
  • 如果是大型系統,對緩存的依賴性比較高,還是建議采用獨立的緩存組件 Redis ,通過主備、集群等形式提高緩存服務的性能和穩定性。