缓存框架Ehcache相关详解编程语言

—恢复内容开始—

单点缓存框架   只能针对单个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使用介绍

 

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内置缓存实现 (为了减轻数据库访问压力)

缓存框架Ehcache相关详解编程语言

 

 内存吃不愁销,限制而容量大小,会有相应的算法处理机制。

 

 

废话不多说,上项目Spring Boot 整合EhCache:

目录结构:

 缓存框架Ehcache相关详解编程语言

 

pom的的本相关依赖:

缓存框架Ehcache相关详解编程语言

这样引入了 就可以为所欲为了   Ehcache底层也是用Map集合实现的 

jar+mapper层的注解+启动类的注解+配置文件+application.yml指定加载的缓配置文件 

 

pom:

<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>

实体类:

package com.toov5.entity; 
 
import lombok.Data; 
 
@Data 
public class Users { 
  private String name; 
  private Integer age; 
}

controller

package com.toov5.controller; 
 
import java.util.List; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
import com.toov5.entity.Users; 
import com.toov5.service.UserService; 
 
@RestController 
public class IndexController { 
       
    @Autowired 
    private UserService userService; 
     
    @RequestMapping("/getUser") 
    public List<Users> getUser(Long id){ 
        return userService.getUser(id); 
    } 
 
}

service

package com.toov5.service; 
 
import java.util.List; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
 
import com.toov5.entity.Users; 
import com.toov5.mapper.UserMapper; 
 
@Service 
public class UserService { 
    @Autowired 
    private UserMapper userMapper; 
     
   public List<Users> getUser(Long id){ 
       return userMapper.getUser(id); 
   } 
}

mapper

package com.toov5.mapper; 
 
import java.util.List; 
 
import org.apache.ibatis.annotations.Param; 
import org.apache.ibatis.annotations.Select; 
import org.springframework.cache.annotation.CacheConfig; 
import org.springframework.cache.annotation.Cacheable; 
 
import com.toov5.entity.Users; 
//引入的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); 
}

启动类:

package com.toov5.app; 
 
import org.mybatis.spring.annotation.MapperScan; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.cache.annotation.EnableCaching; 
 
@EnableCaching //开启缓存 
@MapperScan(basePackages={"com.toov5.mapper"}) 
@SpringBootApplication(scanBasePackages={"com.toov5.*"}) 
public class app { 
   public static void main(String[] args) { 
    SpringApplication.run(app.class, args); 
} 
     
}

 配置文件:

<?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> 

 

###端口号配置 
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 

 缓存框架Ehcache相关详解编程语言

修改数据库的值

 缓存框架Ehcache相关详解编程语言

再次加载

缓存框架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、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。

 

 

解决缓存与DB同步问题 

1、重启服务,jvm也会关闭重启

2、主动通知或者定时Job

 

场景 update 或者delete 容易造成缓存和DB不同步问题   

update语句后 加上通知 主动通知     先修改成功 然后清理缓存 都是在同一个事务中的哟   定时Job健康检查 检查DB和缓存是否一致 然后执行清理缓存

controller加入清缓存的逻辑;

package com.toov5.controller; 
 
import java.util.List; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.cache.CacheManager; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
import com.toov5.entity.Users; 
import com.toov5.service.UserService; 
 
@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); 
    } 
 
}

执行查询后

缓存框架Ehcache相关详解编程语言

修改数据库:

缓存框架Ehcache相关详解编程语言

 

 刷新页面不变,此时调用清理缓存

缓存框架Ehcache相关详解编程语言

再次查询

缓存框架Ehcache相关详解编程语言

好了 成功清理!

 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/16149.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论