案例:java
若是一旦請求到服務器端以後,會在本地緩存一份,快速響應給用戶。mysql
常見的緩存方案:git
總結: 緩存最終的目的是爲減輕服務端壓力,減小網絡傳輸請求github
Session 是存放在服務器端(保存在單個JVM中),返回SessionId(響應頭),客戶端存放的SessionId,下次請求時候,直接使用對於的SessionId從服務器端查詢對應Sessionweb
分佈式Session (Session共享的問題)----直接使用token解決redis
案例單機版: 實現單個JVM緩存框架, Session Key Value 能夠用Map集合實現 過時時間須要好好設計了 寫一個給予Map集合實現Jvm緩存框架:算法
首先定義map實現的緩存類:(concurrentHashmap保證安全)spring
緩存:sql
@Component //這樣的話 就是單例的了!!!注入到容器裏面 public class MapCache<K,V> { //存放緩存容器 public ConcurrentHashMap<K, V> concurrentHashMap = new ConcurrentHashMap<K,V>(); //純手寫單個JVM緩存框架 緩存概念偏向於臨時 //對傳統的Map包裝 public void put(K key,V value){ concurrentHashMap.put(key, value); } //查詢 public V get(K key){ return concurrentHashMap.get(key); } public void remove(String k){ //這個map是安全的 不須要加鎖! concurrentHashMap.remove(k); } }
controller類:數據庫
@RestController public class IndexController { @Autowired private MapCache<String, Object> mapCache; @RequestMapping("/get") public String get(String key){ return (String)mapCache.get(key); } @RequestMapping("/put") public String put(String key, String value){ mapCache.put(key, value); return "成功"; } @RequestMapping("/remove") public String remove(String key){ mapCache.remove(key); return "成功"; } }
啓動類
@SpringBootApplication(scanBasePackages={"com.toov5.*"}) public class app { public static void main(String[] args) { SpringApplication.run(app.class, args); } }
單點緩存框架 只能針對單個jvm中,緩存容器存放jvm中,每一個緩存互不影響 Ehcache gauva chache 內置緩存框架 jvm緩存框架
分佈式緩存技術(共享緩存數據) Redis Meacache
example:
mybatis、hibernate底層都使用了Ehcache
本地緩存Ehcache 什麼是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是用來管理緩存的一個工具,其緩存的數據能夠是存放在內存裏面的,也能夠是存放在硬盤上的。其核心是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,最不常用。在一段時間內,數據被使用次數最少的,優先被淘汰。
注意:
單點緩存框架 只能針對單個jvm中,緩存容器存放jvm中,每一個緩存互不影響 Ehcache gauva chache 內置緩存框架 jvm緩存框架
分佈式緩存技術(共享緩存數據) Redis Meacache
example:
mybatis、hibernate底層都使用了Ehcache
本地緩存Ehcache 什麼是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是用來管理緩存的一個工具,其緩存的數據能夠是存放在內存裏面的,也能夠是存放在硬盤上的。其核心是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,最不常用。在一段時間內,數據被使用次數最少的,優先被淘汰。
注意:
Spring Boot 整合EhCache:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.toov5.architect</groupId> <artifactId>architect</artifactId> <version>0.0.1-SNAPSHOT</version> <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> </project>
實體類:
@Data public class Users { private String name; private Integer age; }
controller:
@RestController public class IndexController { @Autowired private UserService userService; @RequestMapping("/getUser") public List<Users> getUser(Long id){ return userService.getUser(id); } }
Service
@Service public class UserService { @Autowired private UserMapper userMapper; public List<Users> getUser(Long id){ return userMapper.getUser(id); } }
Mapper:
//引入的jar包後就有了這個註解了 很是好用 (配置緩存的基本信息) @CacheConfig(cacheNames={"userCache"}) //緩存的名字 整個類的 public interface UserMapper { @Select("SELECT ID ,NAME,AGE FROM users where id=#{id}") @Cacheable //讓這個方法實現緩存 查詢完畢後 存入到緩存中 不是每一個方法都須要緩存呀!save()就不用了吧 List<Users> getUser(@Param("id") Long id); }
EhCache配置:
<?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-4000" /> <!-- 默認緩存 --> <defaultCache maxElementsInMemory="1000" eternal="true" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="true" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- demo緩存 --><!-- name="userCache" 對應咱們在 @CacheConfig(cacheNames={"userCache"}) !!!!! --> <!--Ehcache底層也是用Map集合實現的 --> <cache name="userCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <!-- LRU緩存策略 --> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> <!-- 用於在初始化緩存,以及自動設置 --> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /> </cache> </ehcache>
yml:
###端口號配置
server:
port: 8080
###數據庫配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
test-while-idle: true
test-on-borrow: true
validation-query: SELECT 1 FROM DUAL
time-between-eviction-runs-millis: 300000
min-evictable-idle-time-millis: 1800000
# 緩存配置讀取
cache:
type: ehcache
ehcache:
config: classpath:app1_ehcache.xml
啓動:
@EnableCaching //開啓緩存 @MapperScan(basePackages={"com.toov5.mapper"}) @SpringBootApplication(scanBasePackages={"com.toov5.*"}) public class app { public static void main(String[] args) { SpringApplication.run(app.class, args); } }
項目結構:
訪問:
備註介紹:【EhCache參數相關】
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、如下屬性是必須的: 1、name: Cache的名稱,必須是惟一的(ehcache會把這個cache放到HashMap裏)。 2、maxElementsInMemory:在內存中緩存的element的最大數目。 3、maxElementsOnDisk:在磁盤上緩存的element的最大數目,默認值爲0,表示不限制。 4、eternal:設定緩存的elements是否永遠不過時。若是爲true,則緩存的數據始終有效,若是爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷。 5、overflowToDisk: 若是內存中數據超過內存限制,是否要緩存到磁盤上。 2、如下屬性是可選的: 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同步DB:
場景描述:
update 或者delete 容易形成緩存和DB不一樣步問題
解決方案:
@RestController public class IndexController { @Autowired private CacheManager cacheManager; @Autowired private UserService userService; //注意引入的jar包是 org.springframework.cache.CacheManager; @RequestMapping("/remoKey") public void remoKey() { cacheManager.getCache("userCache").clear(); //傳入名字 進行清除 } @RequestMapping("/getUser") public List<Users> getUser(Long id){ return userService.getUser(id); } }
1.訪問:
2.修改數據
3.手動清理緩存,接口調用
4.訪問:
因爲 EhCache 是進程中的緩存系統,一旦將應用部署在集羣環境中,每個節點維護各自的緩存數據,當某個節點對緩存數據進行更新,這些更新的數據沒法在其它節點中共享,這不只會下降節點運行的效率,並且會致使數據不一樣步的狀況發生。例如某個網站採用 A、B 兩個節點做爲集羣部署,當 A 節點的緩存更新後,而 B 節點緩存還沒有更新就可能出現用戶在瀏覽頁面的時候,一會是更新後的數據,一會是還沒有更新的數據,儘管咱們也能夠經過 Session Sticky 技術來將用戶鎖定在某個節點上,但對於一些交互性比較強或者是非 Web 方式的系統來講,Session Sticky 顯然不太適合。
EhCache從1.7版本開始,支持五種集羣方案,分別是:
RMi集羣模式 你如何知道集羣環境中的其餘緩存? • 分佈式傳送的消息是什麼形式? • 什麼狀況須要進行復制?增長(Puts),更新(Updates)或是失效(Expiries)? • 採用什麼方式進行復制?同步仍是異步方式? 1、正確的元素類型:只有可序列化的元素能夠進行復制。一些操做,好比移除,只須要元素的鍵值而不用整個元素;在這樣的操做中即便元素不是可序列化的但鍵值是可序列化的也能夠被複制。 2、成員發現(Peer Discovery):Ehcache進行集羣的時候有一個cache組的概念。每一個cache都是其餘cache的一個peer,沒有主cache的存在。成員發現(Peer Discovery)正是用來解決 「你如何知道集羣環境中的其餘緩存?」 這個問題的。Ehcache提供了兩種機制用來進行成員發現,即:自動成員發現和手動成員發現。要使用一個內置的成員發現機制要在ehcache的配置文件中指定cacheManagerPeerProviderFactory元素的class屬性爲 net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory。
注: EhCache支持分佈式緩存 可是不推薦
分佈式緩存圖 :
前言:
實現:
spring boot中集成了spring cache,並有多種緩存方式的實現,如:Redis、Caffeine、JCache、EhCache等等。但若是隻用一種緩存,要麼會有較大的網絡消耗(如Redis),要麼就是內存佔用太大(如Caffeine這種應用內存緩存)。在不少場景下,能夠結合起來實現1、二級緩存的方式,可以很大程度提升應用的處理效率。
spring cache:主要包含spring cache定義的接口方法說明和註解中的屬性說明
補充: 緩存、兩級緩存
簡單的理解,緩存就是將數據從讀取較慢的介質上讀取出來放到讀取較快的介質上,如磁盤-->內存。平時咱們會將數據存儲到磁盤上,如:數據庫。若是每次都從數據庫裏去讀取,會由於磁盤自己的IO影響讀取速度,因此就有了像redis這種的內存緩存。能夠將數據讀取出來放到內存裏,這樣當須要獲取數據時,就可以直接從內存中拿到數據返回,可以很大程度的提升速度。可是通常redis是單獨部署成集羣,因此會有網絡IO上的消耗,雖然與redis集羣的連接已經有鏈接池這種工具,可是數據傳輸上也仍是會有必定消耗。因此就有了應用內緩存,如:caffeine。當應用內緩存有符合條件的數據時,就能夠直接使用,而不用經過網絡到redis中去獲取,這樣就造成了兩級緩存。應用內緩存叫作一級緩存,遠程緩存(如redis)叫作二級緩存
spring boot + spring cache 實現兩級緩存(redis + caffeine)代碼實現:
實體類:
@Data public class Users implements Serializable{ private String name; private Integer age; }
controller
@RestController public class IndexController { @Autowired private UserService userService; @RequestMapping("/userId") public Users getUserId(Long id){ return userService.getUser(id); } }
Service
@Component public class EhCacheUtils { // @Autowired // private CacheManager cacheManager; @Autowired private EhCacheCacheManager ehCacheCacheManager; // 添加本地緩存 (相同的key 會直接覆蓋) public void put(String cacheName, String key, Object value) { Cache cache = ehCacheCacheManager.getCacheManager().getCache(cacheName); Element element = new Element(key, value); cache.put(element); } // 獲取本地緩存 public Object get(String cacheName, String key) { Cache cache = ehCacheCacheManager.getCacheManager().getCache(cacheName); Element element = cache.get(key); return element == null ? null : element.getObjectValue(); } public void remove(String cacheName, String key) { Cache cache = ehCacheCacheManager.getCacheManager().getCache(cacheName); cache.remove(key); } }
@Component public class RedisService { @Autowired private StringRedisTemplate stringRedisTemplate; //這樣該方法支持多種數據類型 public void set(String key , Object object, Long time){ //開啓事務權限 stringRedisTemplate.setEnableTransactionSupport(true); try { //開啓事務 stringRedisTemplate.multi(); String argString =(String)object; //強轉下 stringRedisTemplate.opsForValue().set(key, argString); //成功就提交 stringRedisTemplate.exec(); } catch (Exception e) { //失敗了就回滾 stringRedisTemplate.discard(); } if (object instanceof String ) { //判斷下是String類型不 String argString =(String)object; //強轉下 //存放String類型的 stringRedisTemplate.opsForValue().set(key, argString); } //若是存放Set類型 if (object instanceof Set) { Set<String> valueSet =(Set<String>)object; for(String string:valueSet){ stringRedisTemplate.opsForSet().add(key, string); //此處點擊下源碼看下 第二個參數能夠放好多 } } //設置有效期 if (time != null) { stringRedisTemplate.expire(key, time, TimeUnit.SECONDS); } } //作個封裝 public void setString(String key, Object object){ String argString =(String)object; //強轉下 //存放String類型的 stringRedisTemplate.opsForValue().set(key, argString); } public void setSet(String key, Object object){ Set<String> valueSet =(Set<String>)object; for(String string:valueSet){ stringRedisTemplate.opsForSet().add(key, string); //此處點擊下源碼看下 第二個參數能夠放好多 } } public String getString(String key){ return stringRedisTemplate.opsForValue().get(key); } }
@Component public class UserService { @Autowired private EhCacheUtils ehCacheUtils; @Autowired private RedisService redisService; @Autowired private UserMapper userMapper; //定義個全局的cache名字 private String cachename ="userCache"; public Users getUser(Long id){ //先查詢一級緩存 key以當前的類名+方法名+id+參數值 String key = this.getClass().getName() + "-" + Thread.currentThread().getStackTrace()[1].getMethodName() + "-id:" + id; //查詢一級緩存數據有對應值的存在 若是有 返回 Users user = (Users)ehCacheUtils.get(cachename, key); if (user != null) { System.out.println("key"+key+",直接從一級緩存獲取數據"+user.toString()); return user; } //一級緩存沒有對應的值存在,接着查詢二級緩存 // redis存對象的方式 json格式 而後反序列號 String userJson = redisService.getString(key); //若是rdis緩存中有這個對應的值,修改一級緩存 最下面的會有的 相同會覆蓋的 if (!StringUtil.isNullOrEmpty(userJson)) { //有 轉成json JSONObject jsonObject = new JSONObject();//用的fastjson Users resultUser = jsonObject.parseObject(userJson,Users.class); ehCacheUtils.put(cachename, key, resultUser); return resultUser; } //都沒有 查詢DB Users user1 = userMapper.getUser(id); if (user1 == null) { return null; } //存放到二級緩存 redis中 redisService.setString(key, new JSONObject().toJSONString(user1)); //存放到一級緩存 Ehchache ehCacheUtils.put(cachename, key, user1); return user1; } }
啓動類
@EnableCaching //開啓緩存 @MapperScan(basePackages={"com.toov5.mapper"}) @SpringBootApplication(scanBasePackages={"com.toov5.*"}) public class app { public static void main(String[] args) { SpringApplication.run(app.class, args); } }
app1.ehcache.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-4000" /> <!-- 默認緩存 --> <defaultCache maxElementsInMemory="1000" eternal="true" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="true" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- demo緩存 --><!-- name="userCache" 對應咱們在 @CacheConfig(cacheNames={"userCache"}) !!!!! --> <!--Ehcache底層也是用Map集合實現的 --> <cache name="userCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> <!-- LRU緩存策略 --> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> <!-- 用於在初始化緩存,以及自動設置 --> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" /> </cache> </ehcache>
yml:
###端口號配置
server:
port: 8080
###數據庫配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
test-while-idle: true
test-on-borrow: true
validation-query: SELECT 1 FROM DUAL
time-between-eviction-runs-millis: 300000
min-evictable-idle-time-millis: 1800000
# 緩存配置讀取
cache:
type: ehcache
ehcache:
config: classpath:app1_ehcache.xml
redis:
database: 0
host: 192.168.91.3
port: 6379
password: 123
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
timeout: 10000
運行結果
後面的訪問,在控制檯打印:
代碼必定要注意:
分佈式緩存的思考: