SpringBoot2.0整合Ehcache

1、pom.xml添加依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<!-- SpringBoot 對lombok 支持 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<!-- SpringBoot web 核心組件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</dependency>
		<!-- SpringBoot 外部tomcat支持 -->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
		<!-- springboot-log4j -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j</artifactId>
			<version>1.3.8.RELEASE</version>
		</dependency>
		<!-- springboot-aop 技術 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<!--開啓 cache 緩存 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<!-- ehcache緩存 -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.1.1</version>
		</dependency>
		<!-- mysql 依賴 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
	</dependencies>

2、在需要換成的Mapper.java 中,添加註解

/**
 * 功能說明: <br>
 * @CacheConfig 配置緩存基本信息 cacheNames緩存名稱
 * @Cacheable 配置緩存, 使該方法查詢數據庫完畢後 存入到緩存中
 * 
 */
@CacheConfig(cacheNames = "userCache")
public interface UserMapper {
	@Select("SELECT ID ,NAME,AGE FROM users where id=#{id}")
	@Cacheable
	List<Users> getUser(@Param("id") Long id);
}

3、springBoot啓動類中開啓緩存註解


/**
 * 功能說明:@EnableCaching 開啓緩存功能 <br>
 
 */
@MapperScan(basePackages = { "com.itmayiedu.mapper" })
@EnableCaching
@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

4、在src/main/resourecs 下 編寫ehcahe.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

	<diskStore path="java.io.tmpdir/ehcache-rmi-5000" />

	<!-- 默認緩存 -->
	<defaultCache maxElementsInMemory="1000" eternal="true"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
		diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
		diskPersistent="true" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
	</defaultCache>

	<!-- demo緩存 -->
	<cache name="userCache" maxElementsInMemory="1000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
		diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
		diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
		<cacheEventListenerFactory
			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
		<!-- 用於在初始化緩存,以及自動設置 -->
		<bootstrapCacheLoaderFactory
			class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
	</cache>
</ehcache>

5、在yml文件中配置緩存讀取   app2_ehcache.xml爲前面配置文件的名稱

  # 緩存配置讀取
  cache:
    type: ehcache
    ehcache:
      config: classpath:app2_ehcache.xml

6、如何解決緩存與DB不同步問題

主動通知,在修改和刪除的方法中,操作完數據庫後,主動清理緩存

	@Autowired
	private MapEhcaChe<String, String> mapEhcaChe;

	@RequestMapping("/remoKey")
	public void remoKey() {
		cacheManager.getCache("userCache").clear();
	}

爲保萬一,也可以使用定時job,更新緩存信息

 

什麼是Ehcache

 Ehcache是純java的開源緩存框架,具有快速、精幹等特點,是Hibernate中默認的CacheProvider。它主要面向通用緩存、Java EE和輕量級容器,具有內存和磁盤存儲、緩存加載器、緩存擴展、緩存異常處理程序。

 Ehcache最初由Greg Luck於2003年開始開發。2009年,該項目被Terracotta購買。軟件仍然開源,但一些新的主要功能(例如,快速可重啓性之間的一致性的)只能在商業產品中使用。

Ehcache 被廣泛用於在Hibernate、Spring、Cocoon等其他開源系統。

Ehcache的主要特性

1.快速;

2.簡單;

3.多種緩存策略;

4.緩存數據有兩級:內存和磁盤,因此無需擔心容量問題;

5.緩存數據會在虛擬機重啓的過程中寫入磁盤;

6.可以通過 RMI、可插入 API 等方式進行分佈式緩存;

7.具有緩存和緩存管理器的偵聽接口;

8.支持多緩存管理器實例,以及一個實例的多個緩存區域;

9.提供 Hibernate 的緩存實現;

 

Ehcache使用介紹

Ehcache是用來管理緩存的一個工具,其緩存的數據可以是存放在內存裏面的,也可以是存放在硬盤上的。其核心是CacheManager,一切Ehcache的應用都是從CacheManager開始的。它是用來管理Cache(緩存)的,一個應用可以有多個CacheManager,而一個CacheManager下又可以有多個Cache。Cache內部保存的是一個個的Element,而一個Element中保存的是一個key和value的配對,相當於Map裏面的一個Entry。

Ehcache緩存過期策略

當緩存需要被清理時(比如空間佔用已經接近臨界值了),需要使用某種淘汰算法來決定清理掉哪些數據。常用的淘汰算法有下面幾種:

FIFO:First In First Out,先進先出。判斷被存儲的時間,離目前最遠的數據優先被淘汰。

LRU:Least Recently Used,最近最少使用。判斷最近被使用的時間,目前最遠的數據優先被淘汰。

LFU:Least Frequently Used,最不經常使用。在一段時間內,數據被使用次數最少的,優先被淘汰。

 

1、diskStore :指定數據(.data and .index)存儲位置,可指定磁盤中的文件夾位置期 The diskStore element is optional. It must be configured if you have overflowToDisk or diskPersistent enabled    for any cache. If it is not configured, a warning will be issues and java.io.tmpdir will be used.

2、defaultCache : 默認的管理策略

Ehcache 使用Map集合實現的 element 其實就是 key 和value

一、以下屬性是必須的:

  1、name: Cache的名稱,必須是唯一的(ehcache會把這個cache放到HashMap裏)。

  2、maxElementsInMemory:在內存中緩存的element的最大數目。

  3、maxElementsOnDisk:在磁盤上緩存的element的最大數目,默認值爲0,表示不限制。

  4、eternal:設定緩存的elements是否永遠不過期。如果爲true,則緩存的數據始終有效,如果爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷。

  5、overflowToDisk: 如果內存中數據超過內存限制,是否要緩存到磁盤上。

二、以下屬性是可選的:

  1、timeToIdleSeconds: 對象空閒時間,指對象在多長時間沒有被訪問就會失效。只對eternal爲false的有效。默認值0,表示一直可以訪問。

  2、timeToLiveSeconds: 對象存活時間,指對象從創建到失效所需要的時間。只對eternal爲false的有效。默認值0,表示一直可以訪問。

  3、diskPersistent: 是否在磁盤上持久化。指重啓jvm後,數據是否有效。默認爲false。

  4、diskExpiryThreadIntervalSeconds: 對象檢測線程運行時間間隔。標識對象狀態的線程多長時間運行一次。

  5、diskSpoolBufferSizeMB: DiskStore使用的磁盤大小,默認值30MB。每個cache使用各自的DiskStore。

  6、memoryStoreEvictionPolicy: 如果內存中數據超過內存限制,向磁盤緩存時的策略。默認值LRU,可選FIFO、LFU。

Ehcache集羣模式

由於 EhCache 是進程中的緩存系統,一旦將應用部署在集羣環境中,每一個節點維護各自的緩存數據,當某個節點對緩存數據進行更新,這些更新的數據無法在其它節點中共享,這不僅會降低節點運行的效率,而且會導致數據不同步的情況發生。例如某個網站採用 A、B 兩個節點作爲集羣部署,當 A 節點的緩存更新後,而 B 節點緩存尚未更新就可能出現用戶在瀏覽頁面的時候,一會是更新後的數據,一會是尚未更新的數據,儘管我們也可以通過 Session Sticky 技術來將用戶鎖定在某個節點上,但對於一些交互性比較強或者是非 Web 方式的系統來說,Session Sticky 顯然不太適合。

常用集羣模式

EhCache從1.7版本開始,支持五種集羣方案,分別是:

Terracotta、RMI、JMS、JGroups、EhCache Server

1、正確的元素類型:只有可序列化的元素可以進行復制。一些操作,比如移除,只需要元素的鍵值而不用整個元素;在這樣的操作中即使元素不是可序列化的但鍵值是可序列化的也可以被複制。

2、成員發現(Peer Discovery):Ehcache進行集羣的時候有一個cache組的概念。每個cache都是其他cache的一個peer,沒有主cache的存在。成員發現(Peer Discovery)正是用來解決 “你如何知道集羣環境中的其他緩存?” 這個問題的。Ehcache提供了兩種機制用來進行成員發現,即:自動成員發現和手動成員發現。要使用一個內置的成員發現機制要在ehcache的配置文件中指定cacheManagerPeerProviderFactory元素的class屬性爲

net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory。

Ehcache的使用場景

使用純java的ehcache作爲本地緩存

Reids 作爲遠程分佈式緩存

解決redis緩存壓力過大,提高緩存速度,以及緩存性能。

Redis和Ehcache緩存的區別

如果是單個應用或者對緩存訪問要求很高的應用,用ehcache。
如果是大型系統,存在緩存共享、分佈式部署、緩存內容很大的,建議用redis。

實際工作中使用Ehcache

在項目中使用集中式緩存(Redis或者式Memcached等),通常都是檢查緩存中是否存在

期望值的數據,如果存在直接返回,如果不存在就查詢數據庫後在將數據庫緩存,

 

這個時候如果緩存系統因爲某寫原因宕機,造成服務無法訪問,那麼大的量請求直接穿透到數據庫,最數據庫壓力非常大。

這時候我們讓ehcache作爲二級緩存,當redis服務器宕機後,可以查詢ehcache緩存。

這樣能夠有效的扛住服務器請求壓力。

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