# RCache **Repository Path**: mosangshen/rcache ## Basic Information - **Project Name**: RCache - **Description**: Rcache是一个缓存框架,其核心设计目的是为了让我们可以更加灵活的去配置缓存,其学习简单、轻量级、易扩展开箱即用。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-05-26 - **Last Updated**: 2025-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 介绍|Introduce Rcache是一个缓存框架,其核心设计目的是为了让我们可以更加灵活的去配置缓存,其学习简单、轻量级、易扩展开箱即用。 ## 河北软件职业技术学院2020级JavaPlus **作者**:高增源、钱国鹏、李佳成、贺建豪 **指导教师**:王彦辉 # 特性|Speciality 1. 轻量级:RCache最简包仅仅依赖log4j 2. 模块化:RCache将分布式策略、连接持久层框架代码进行了分离,用时导入插件包即可,即插即用 3. 灵活性: - CacheManager管理的为动态代理的RCache可以很简单的对其进行功能增强 - 增加了MultipleCache策略,可以灵活搭配RCache食用 4. 持久化:ALWAYS(每新增一个缓存元素就进行一次缓存)、SIZE(根据缓存元素数量设定阈值,达到阈值进行持久化)、TIME(根据用户设定的时间定时缓存)持久化异步进行 5. 邮件报警:在缓存元素数量达到预警阈值会异步发送邮件报警、分布式环境客户机掉线、重新选举后会异步发送邮件报警 6. 分布式:目前支持Netty分布式策略异步通信(后面会更新NIO分布式策略) 7. 可用性:可连接mybatis与hibernate持久化框架、模块化拆分即插即用 # 架构图|Structure Chart(简版|Simple) ![架构图](%E6%9E%B6%E6%9E%84%E5%9B%BE.png) # 快速开始|Quick Start **添加依赖** **添加最简包:**[RabbitCache_Simple.jar](https://gitee.com/mosangshen/rcache/raw/master/%E6%9C%AC%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E7%9A%84jar%E5%8C%85/RabbitCache_Simple.jar) **配置文件示例** 在资源根目录创建 rcache.properties 文件 ```properties # cache名称 CacheName=cache1 # 淘汰策略 可配置 FIFO、LRU、LFU、Multiple 默认FIFO cache1.cacheStrategy=LFU ################## 生命周期配置 ################## # 最大存活时间 eternal为false时生效 10000(十秒) cache1.maxTimeToLive=10000 # 最大空闲时间 eternal为false时生效 默认2000(两秒) cache1.maxTimeToIdle=2000 # 是否永不过期 默认为false cache1.eternal=false ################## 持久化配置 ################## # 是否开启持久化 cache1.diskCache=true # 持久化路径 cache1.diskCachePath=D:/cache # 持久化策略 可配置:TIME、SIZE、ALWAYS 默认always cache1.diskCacheStrategy=TIME # TIME持久化策略配置 定时时间 默认10秒,在持久化策略为SIZE时生效 cache1.diskCacheTime=10000 # SIZE持久化策略配置 阈值 默认达到15个元素存储一次,在持久化策略为TIME时生效 cache1.diskCacheSize=15 ################## 容量限制配置 ################## # 初始容量 cache1.initElements=2 # 最大元素数量 cache1.maxElements=1000 ################## 邮件预警配置 ################## # 容量预警阈值 cache1.warningElements=7 # 是否开启邮件预警 cache1.warning=true # 预警信息发送的邮箱账号 cache1.managerEmail=mosangshen@163.com ################## 分布式缓存配置 ################## # 是否开始分布式 cache1.distribute=true # master IP cache1.distributeIP=192.168.119.1 # master Port cache1.distributePort=8888 ``` ## 整合Hibernate篇 ### 添加依赖 **Hibernate3:**[RabbitCache_Hibernate3.jar](https://gitee.com/mosangshen/rcache/raw/master/%E6%9C%AC%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E7%9A%84jar%E5%8C%85/RabbitCache_Hibernate3.jar) **Hibernate4:**[RabbitCache_Hibernate4.jar](https://gitee.com/mosangshen/rcache/raw/master/%E6%9C%AC%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E7%9A%84jar%E5%8C%85/RabbitCache_Hibernate4.jar) ### **配置** 在资源根目录创建 rcache.properties 、hibernate.cfg.xml、User.hbm.xml文件 **hibernate.cfg.xml** ```xml org.hibernate.dialect.MySQLDialect jdbc:mysql://localhost:3308/testmybatis?useUnicode=true&characterEncoding=utf-8 root root com.mysql.jdbc.Driver true false update thread true true com.hibernate.rcache.RcacheRegionFactory ``` **User.hbm.xml** ```xml ``` ### **测试示例** ```java public class Test { public static void main(String[] args) throws ConfigurationException { // 1.加载配置文件 Configuration config = new Configuration().configure(); // 2.创建session工厂 SessionFactory sessionFactory = config.buildSessionFactory(); // 3.获取session Session session = sessionFactory.openSession(); // 4.开启事务 Transaction transaction = session.beginTransaction(); // 5.进行持久化操作(CRUD) //第一次查询 查询缓存--->未命中--->查询数据库 User user2 = (User) session.get(User.class, "1"); System.out.println(user2.getName()); //第二次查询 查询缓存--->命中 user2 = (User) session.get(User.class, "1"); System.out.println(user2.getName()); //验证是否存入缓存 CacheManager cacheManager = CacheManager.newInstance(); System.out.println("CacheNames:"+cacheManager.getCacheNames()); Map map = cacheManager.getCache("entity.User").toMap(); for ( Object key:map.keySet()){ System.out.println("element: "+map.get(key)); } user2 = (User) session.get(User.class, "1");//从数据库获取 // 6.提交事务 transaction.commit(); // 7.关闭连接 session.close(); } } ``` ## 整合Mybatis篇 ### 添加依赖 [RabbitCache_Mybatis.jar](https://gitee.com/mosangshen/rcache/raw/master/%E6%9C%AC%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E7%9A%84jar%E5%8C%85/RabbitCache_Mybatis.jar) ### 配置 在资源根目录创建 rcache.properties 、mybatis-config.xml、UserMapper.xml文件 **mybatis-config.xml** ```xml ``` **UserMapper.xml** ```java ``` ### 测试示例 ```java public class Test01 { public static void main(String[] args) throws IOException, ConfigurationException, InterruptedException { for (int i = 0; i < 2; i++) { System.err.println("第"+i+"次查询………………"); String config="mybatis-config.xml"; Reader reader = Resources.getResourceAsReader(config); SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader); SqlSession session = sessionFactory.openSession(); //1.查询全部 session.selectList("queryAll"); //获取cacheManager CacheManager cacheManager= CacheManager.newInstance(); System.out.println(cacheManager.getCacheNames()); //得到Rcache对象 Rcache cache = cacheManager.getCache("default"); System.out.println("cache.KeySet()"+cache.KeySet()); session.close(); System.out.println("cache.KeySet():"+cache.KeySet()); System.out.println("\n\n\n"); } } } ``` ## RCache分布式篇 ### 添加依赖 [RabbitCache_Netty4.jar](https://gitee.com/mosangshen/rcache/raw/master/%E6%9C%AC%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E7%9A%84jar%E5%8C%85/RabbitCache_Netty4.jar) ### 配置 在资源根目录创建 rcache.properties 文件 ```properties # cache名称 CacheName=cache1 ################## 分布式缓存配置 ################## # 是否开始分布式 cache1.distribute=true # master IP cache1.distributeIP=192.168.119.1 # master Port cache1.distributePort=8888 ``` **使用分布式方法** put(key,value,true); update(key,value,true); delete(key,true); ### 测试示例 ```java public class Test { private static Rcache cache; public static void main(String[] args) throws Exception { ICacheManager cacheManager = CacheManager.newInstance("classpath:rcache.properties"); //使用cache1缓存池 cache= cacheManager.getCache("cache1"); System.out.println(cacheManager.getCacheNames()); Thread.sleep(2000); cs(); } /** * @desc 测试缓存 */ private static void cs() { //获取扫描器对象 String inStr; Scanner s=new Scanner(System.in); while (true){ System.out.println("-----控制台测试阶段-----"); System.out.println("进行添加操作,请输入 put"); System.out.println("进行修改操作,请输入 update"); System.out.println("进行删除操作,请输入 delete"); System.out.println("进行查询操作,请输入 query"); inStr = s.nextLine(); if (inStr.equals("put")){ System.out.println("-----进入添加操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); System.out.println("-----请输入value值-----"); String value = s.nextLine(); put(key,value,true); }else if (inStr.equals("update")){ System.out.println("-----进入修改操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); System.out.println("-----请输入value值-----"); String value = s.nextLine(); update(key,value,true); }else if (inStr.equals("delete")){ System.out.println("-----进入删除操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); delete(key,true); }else if (inStr.equals("query")){ System.out.println("-----进入查询操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); query(key); }else if (inStr.equals("quit")){ System.exit(0); } } } private static void update(String key, String value, boolean b) { cache.replace(key,value,b); } private static void delete(String key, boolean b) { cache.remove(key,b); } private static void put(String key, String value, boolean b) { cache.put(key,value,b); } private static void query(String key) { Object value = cache.get(key); System.out.println(key+" 对应的值为:"+value); } } ``` ## MultipleCache使用案例 ### 配置 在资源根目录创建 rcache.properties 文件 ```properties # cache名称 CacheName=cache_duoduo,cache1,cache2 ###### cache1 ###### # 是否永不过期 默认为false cache1.eternal=true # 淘汰策略 默认fifo cache1.cacheStrategy=LFU ###### cache2 ###### # 是否永不过期 默认为false cache2.eternal=true # 淘汰策略 默认fifo cache2.cacheStrategy=LRU ###### cache2 ###### # 淘汰策略 设置为Multiple cache_duoduo.cacheStrategy=Multiple # 配置缓存策略:(可灵活搭配,根据业务场景配置缓存提高命中率)将cache1充当L1,cache2充当L2,在L1中淘汰后进入L2……直到最后一层删除缓存元素 cache_duoduo.cacheNames=cache1,cache2…… ``` ### 测试示例 ```java public class Test { private static Rcache cache; public static void main(String[] args) throws Exception { ICacheManager cacheManager = CacheManager.newInstance("classpath:rcache.properties"); //使用cache_duoduo缓存池 cache= cacheManager.getCache("cache_duoduo"); System.out.println(cacheManager.getCacheNames()); Thread.sleep(2000); cs(); } /** * @desc 测试缓存 */ private static void cs() { //获取扫描器对象 String inStr; Scanner s=new Scanner(System.in); while (true){ System.out.println("-----控制台测试阶段-----"); System.out.println("进行添加操作,请输入 put"); System.out.println("进行修改操作,请输入 update"); System.out.println("进行删除操作,请输入 delete"); System.out.println("进行查询操作,请输入 query"); inStr = s.nextLine(); if (inStr.equals("put")){ System.out.println("-----进入添加操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); System.out.println("-----请输入value值-----"); String value = s.nextLine(); put(key,value,true); }else if (inStr.equals("update")){ System.out.println("-----进入修改操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); System.out.println("-----请输入value值-----"); String value = s.nextLine(); update(key,value,true); }else if (inStr.equals("delete")){ System.out.println("-----进入删除操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); delete(key,true); }else if (inStr.equals("query")){ System.out.println("-----进入查询操作-----"); System.out.println("-----请输入key值-----"); String key = s.nextLine(); query(key); }else if (inStr.equals("quit")){ System.exit(0); } } } private static void query(String key) { Object value = cache.get(key); System.out.println(key+" 对应的值为:"+value); } private static void delete(String key) { cache.remove(key); } private static void update(String key, String value) { cache.replace(key,value); } public static void put(String key, String value){ cache.put(key,value); } } ``` # 期望 | Futures > 欢迎提出更好的意见 **mosangshen@163.com**