# cacheChen **Repository Path**: iwantyou/cacheChen ## Basic Information - **Project Name**: cacheChen - **Description**: chache缓存框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2017-08-09 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 前世今生 > java开发中,针对主流网站,流量大的网站都会使用缓存,目前流行的缓存框架很多,其中表现的最优秀的redis,算是佼佼者。 缓存库只是用来存储读取数据,使用java操作redis,需要手动一个一个的调用命令非常麻烦, 著名框架spring中提供了使用一套缓存注解操作缓存库,虽然通过配置可以使用redis,但是差强人意。 于是spring cache定制版cacheChen悄然问世。 # cacheChen 是什么 框架基于spring cache 重构,由国内资深人气工程师亲历打造轻量级redis缓存框架,旨在增加开发效率,和redis完美集合. cacheChen的问世解决了spring 注解不具备的功能,解决缓存雪崩 穿透 问题,支持配置失效时间等强大功能难以想象。 # 用到了什么 1. lombok https://projectlombok.org/ 2. spring boot 2. jedis ``` redis.clients jedis 2.9.0 ``` # 功能说明 >1. 缓存批量命中,批量处理 >2. 解决缓存穿透问题 >3. 解决缓存雪崩问题 >4. 支持配置缓存失效时间 >5. 实现缓存的读写分离,不同cacheName 配置不同的读写库 >6. 支持spring 4.0+ cache 注解功能 # 新增功能(20170813更新) * cacheName 同步key分布式锁功能 >1. 配置 ``` /** * 是否开启缓存key分布式锁 */ redisConfig.setDistributedLock(true); ``` >2. 参考 http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/concurrent/distributed/DistributedLock.java # 基本配置 ``` @Configuration public class Config { @Bean public BeanFactoryCacheOperationAdvisor cacheAdvisor(){ BeanFactoryCacheOperationAdvisor advisor = new BeanFactoryCacheOperationAdvisor(); advisor.setAdvice(cacheInterceptor()); return advisor; } @Bean public CacheInterceptor cacheInterceptor(){ return new CacheInterceptor(); } } ``` ``` /** * 创建cache manager * @return */ @Bean public CacheManager createCacheManager(){ RedisConfig redisConfig = new RedisConfig(); redisConfig.setDefaultReadSourceName("read"); redisConfig.setDefaultWriteSourceName("write"); JedisPoolConfig config = new JedisPoolConfig(); //连接耗尽时是否阻塞, false报异常,true 阻塞直到超时, 默认true config.setBlockWhenExhausted(true); //设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数) config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy"); //是否启用pool的jmx管理功能, 默认true config.setJmxEnabled(true); //MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "poolConfig" + i); 默认为"poolConfig", JMX不熟,具体不知道是干啥的...默认就好. config.setJmxNamePrefix("poolConfig"); //是否启用后进先出, 默认true config.setLifo(true); //最大空闲连接数, 默认8个 config.setMaxIdle(8); //最大连接数, 默认8个 config.setMaxTotal(8); //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 config.setMaxWaitMillis(-1); //逐出连接的最小空闲时间 默认1800000毫秒(30分钟) config.setMinEvictableIdleTimeMillis(1800000); //最小空闲连接数, 默认0 config.setMinIdle(0); //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 config.setNumTestsPerEvictionRun(3); //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略) config.setSoftMinEvictableIdleTimeMillis(1800000); //在获取连接的时候检查有效性, 默认false config.setTestOnBorrow(false); //在空闲时检查有效性, 默认false config.setTestWhileIdle(false); //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1 config.setTimeBetweenEvictionRunsMillis(-1); // poolConfig.setTestWhileIdle(true); // poolConfig.setTestOnBorrow(true); RedisSource[] sources = new RedisSource[2]; RedisSource readRedisSource = new RedisSource(); readRedisSource.setSourceName("read"); readRedisSource.setIp("192.168.0.118"); readRedisSource.setPort(6379); readRedisSource.setPassword("chen"); readRedisSource.setPoolConfig(config); RedisSource writeRedisSource = new RedisSource(); writeRedisSource.setSourceName("write"); writeRedisSource.setIp("192.168.0.118"); writeRedisSource.setPort(6379); writeRedisSource.setPassword("chen"); writeRedisSource.setPoolConfig(config); sources[0] = readRedisSource; sources[1] = writeRedisSource; redisConfig.setSources(sources); /** * 是否开启缓存key分布式锁 */ redisConfig.setDistributedLock(true); CacheManager cacheManager = new CacheManager(redisConfig); return cacheManager; } ``` # 使用说明 * CacheConfig http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/annotation/CacheConfig.java --- * Cacheable http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/annotation/Cacheable.java --- * CachePut http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/annotation/CachePut.java --- * CacheEvict http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/annotation/Cacheable.java --- * Caching http://git.oschina.net/iwantyou/cacheChen/blob/master/src/main/java/org/chen/cache/annotation/Caching.java # 使用案例 ``` //-------- Cacheable demo 开始 ------------------------------------------------------------- @Cacheable(key = "#userId",cacheTime = 1000 * 50) public User get(Integer userId){ return get(userId, null); } @Cacheable(key = "#userId",readSourceName = "test1",writeSourceName = "test2") public User getBySourceName(Integer userId){ return get(userId, null); } @Cacheable(key = "#userId",sync = true) public User getSync(Integer userId){ return get(userId, null); } @Caching(cacheable={@Cacheable(key = "#userId"),@Cacheable(key = "#email")}) public User get(Integer userId, String email){ User user = new User(); user.setId(userId); user.setEmail(email); user.setName("测试"); user.setCreateTime(new Date()); return user; } @Cacheable(resultCacheKey = "id",batch = true) public ArrayList batchGet(Collection userIds){ ArrayList list = new ArrayList<>(); for (Integer userId : userIds) { User user = new User(); user.setId(userId); user.setName("批量测试"); user.setCreateTime(new Date()); list.add(user); } return list; } @Cacheable(resultCacheKey = "id",cacheNull = true,batch = true) public ArrayList batchGetCacheNull(Collection userIds){ return batchGet(userIds); } @Cacheable(resultCacheKey = "id",slide = true,batch = true) public List batchSlide(Collection userIds){ return batchGet(userIds); } //-------- Cacheable demo 结束 ------------------------------------------------------------- //-------- CachePut demo 开始 ------------------------------------------------------------- @CachePut(cacheNames = "test",resultCacheKey = "id",batch = true) public List batchPut(Collection userIds){ ArrayList list = new ArrayList<>(); for (Integer userId : userIds) { User user = new User(); user.setId(userId); user.setName("批量put测试"); user.setCreateTime(new Date()); list.add(user); } return list; } @Caching(put={@CachePut(resultCacheKey = "userId"),@CachePut(resultCacheKey = "email")}) public List batchPutMuiltResultCacheKey(Collection userIds){ return batchPut(userIds); } //-------- CachePut demo 结束 ------------------------------------------------------------- //-------- CacheEvict demo 开始 ------------------------------------------------------------- @CacheEvict(key="#userId") public void remove(Integer userId){ } @Caching(evict={@CacheEvict(key="#userId"),@CacheEvict(key="#email")}) public void batchRemove(Integer userId,String email){ } //-------- CacheEvict demo 结束 ------------------------------------------------------------- ``` # 使用案例之SimpleCacheNameJedis ``` org.chen.cache.manager.jedis.SimpleCacheNameJedis 该类的功能可以不使用注解的情况下,实现一个cacheName 简单的 put get remove 操作 例如: SimpleCacheNameJedis cache = SimpleCacheNameJedis.getInstance("test_cache_name"); cache.put("test","小李子"); String t = cache.get("test"); cache.remove("test"); 上面的缓存都存在名字叫test_cache_name的cacheName下 ``` #下载 http://git.oschina.net/iwantyou/cacheChen