刘凯雄 096d50dcd3 重新定位版本号,并为mongo重新添加监控埋点 2 years ago
..
src 24e09b3be1 增加文档、以及功能的优化 4 years ago
README.md 24e09b3be1 增加文档、以及功能的优化 4 years ago
pom.xml 096d50dcd3 重新定位版本号,并为mongo重新添加监控埋点 2 years ago
pom.xml.versionsBackup e9e9d08e5d 将SVN的核心代码移交到Git 5 years ago

README.md

elab-cache 使用注意事项

使用步骤:

  1. 引入maven的依赖

    <dependency>
    <groupId>com.elab.cache</groupId>
    <artifactId>elab-cache</artifactId>
    <version>1.4</version>
    </dependency>
    
  2. 在配置文件中配置使用的对象

     <!-- 默认生成的缓存key的实现策略 -->
    <bean id="defaultCacheKeyGenerator" class="com.elab.cache.spring.generator.DefaultCacheKeyGenerator">
        <property name="prefix" value="demo"/>
        <property name="separator" value="_"/>
    </bean>
            
    <!-- 开启cache注解扫描 -->
    <cache:annotation-driven cache-manager="cacheManager" key-generator="defaultCacheKeyGenerator"/>
    
    <!-- redis 集群操作类 -->
    <bean id="redisClusterClient" class="com.elab.cache.redis.RedisClusterClient" init-method="init" lazy-init="true">
        <property name="redisBuilder" ref="redisClusterBuilder"></property>
    </bean>
    
    <!-- redis 主备操作类 -->
    <bean id="redisSentineClient" class="com.elab.cache.redis.RedisSentinelClient" init-method="init" lazy-init="true">
        <property name="redisBuilder" ref="redisSentinelBuilder"/>
         <property name="password" value="elab@123"/>
        <property name="dbIndex" value="2"/>
    </bean>
    
    <!-- redis 单机操作类 -->
    <bean id="redisStandaloneClient" class="com.elab.cache.redis.RedisStandaloneClient" init-method="init"
          lazy-init="true">
        <property name="redisBuilder" ref="redisStandaloneBuilder"/>
        <property name="password" value="elab@123"/>
        <property name="dbIndex" value="2"/>
    </bean>
    
    <!-- 集群连接池配置 -->
    <bean id="redisPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
        <property name="maxTotal" value="160"/>
        <property name="maxIdle" value="160"/>
        <property name="minIdle" value="80"/>
        <property name="maxWaitMillis" value="1000"/>
        <property name="jmxNamePrefix" value="jedis-pool"/>
        <property name="jmxEnabled" value="true"/>
    </bean>
    
    <!-- 集群版redis操作 -->
    <bean id="redisClusterBuilder" class="com.sohu.tv.builder.RedisClusterBuilder" lazy-init="true">
        <constructor-arg value="10021"/>
        <property name="jedisPoolConfig" ref="redisPoolConfig"/>
        <property name="connectionTimeout" value="2000"/>
        <property name="soTimeout" value="1000"/>
    </bean>
    
    <!-- 单机版redis 操作 -->
    <bean id="redisStandaloneBuilder" class="com.sohu.tv.builder.RedisStandaloneBuilder" lazy-init="true">
        <constructor-arg value="10002"/>
        <property name="timeout" value="2000"/>
        <property name="poolConfig" ref="redisPoolConfig"/>
    </bean>
    
    <!-- redisSentine操作 -->
    <bean id="redisSentinelBuilder" class="com.sohu.tv.builder.RedisSentinelBuilder" lazy-init="true">
        <constructor-arg value="10020"/>
        <property name="poolConfig" ref="redisPoolConfig"/>
        <property name="connectionTimeout" value="2000"/>
        <property name="soTimeout" value="1000"/>
    </bean>
    
    <!-- 将默认的实现集成到spring-cache中 -->
    <bean id="systemCacheManage" class="com.elab.cache.spring.manage.SystemCacheManage">
        <property name="cacheClient" ref="redisStandaloneClient"/>
        <property name="timeout" value="30000"/>
        <property name="name" value="redisClient"/>
    </bean>
    
    <!-- 简单的缓存管理器 -->
    <bean id="simpleCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches" ref="systemCacheManage"/>
    </bean>
    
    <!-- 统一的缓存管理器 -->
    <bean id="cacheManager"
          class="org.springframework.cache.support.CompositeCacheManager">
        <property name="cacheManagers">
            <list>
                <ref bean="simpleCacheManager"/>
            </list>
        </property>
        <property name="fallbackToNoOpCache" value="true"/>
    </bean>
    
  3. 代码层面如何使用,具体需要 ```

// 这里需要注意的是定义了CacheConfig相当于对这个类定义了全局的缓存配置 // 下面的value可以不用定义了 -> @Cacheable(value = "redisClient") @CacheConfig(cacheNames = "redisClient") public class ServiceImpl implements IService {

// 需要注意的是
// 第一个参数与配置文件中的systemCacheManage.name 参数要保持一致,这个注解是为了标识你要使用那个缓存
// 第二个参数是key生成的策略,不填默认[类_方法名_JSON参数],下面的生成最后lkx_test_2,表示自己指定的
// 第三个参数表示条件,表示redisModel的id不能为空才会进行缓存
@Cacheable(value = "redisClient", key = "'lkx_test_'+#redisModel.id" ,condition = "#redisModel.id != null")
public String test(RedisModel redisModel) {
    System.out.println("执行完毕");
    return "你好啊~~";
}

/**

 * 每次都执行更新操作的注解
 * @param redisModel
 * @return
 */
@CachePut(value = "redisClient", key = "'lkx_test_'+#redisModel.id")
public String updateCache(RedisModel redisModel) {
    System.out.println("执行修改完毕..");
    return "OK";
}

/**
 * allEntries : 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
 * beforeInvocation : 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
 *
 * @param redisModel
 * @return
 */
@CacheEvict(value = "redisClient", key = "'lkx_test_'+#redisModel.id", allEntries = false, beforeInvocation = false)
public String CacheEvict(RedisModel redisModel) {
    System.out.println("执行del完毕..");
    return "OK~";
}
}
**注意**
1. 集合如何更新  
    自定义的key的话最好有规律可循,例如再缓存了多个集合的情况出现数据更新就比较麻烦了,
    所以推荐key的定义方式[project_class_list_method],这种的话,在更新缓存的时候,方便通过[project_class_list]为前缀的key全部删除掉,重新加载
2. CachePut在没有集合出现的情况比较适合,但是如果缓存的集合比较多,要做更新的话就会比较麻烦

5. 参考案例
RedisTest.testCache

6. 异常处理
> 当redis遇到异常导致停止时,不能导致应用无法使用

参考类: SimpleCacheErrorProcess , 里面是你具体的业务实现

public class SimpleCacheErrorProcess implements CacheErrorProcess {

Logger logger = LoggerFactory.getLogger(getClass());

@Override
public void handleCacheGetError(RuntimeException exception, ICacheClient cache, Object key) {
    logger.error("==============handleCacheGetError==================== [key]" + key, exception);
}

@Override
public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object value) {
    logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value, exception);
}

@Override
public void handleCachePutError(RuntimeException exception, ICacheClient cache, Object key, Object filed, Object value) {
    logger.error("==============handleCachePutError==================== [key]" + key + "=======[value]" + value + "========[filed]========" + filed, exception);
}

@Override
public void handleCacheEvictError(RuntimeException exception, ICacheClient cache, Object key) {
    logger.error("==============handleCacheEvictError====================", exception);
}

@Override
public void handleCacheClearError(RuntimeException exception, ICacheClient cache) {
    logger.error("==============handleCacheClearError====================", exception);
}

}


然后在spring中进行配置将这个SimpleCacheErrorProcess注入到每个redis的cacheErrorProcess属性中就行了

<bean id="redisStandaloneClient" class="com.elab.cache.redis.RedisStandaloneClient" init-method="init"

      lazy-init="true">
    <property name="redisBuilder" ref="redisStandaloneBuilder"/>
    <property name="cacheErrorProcess" ref="你的实现类"/>

```

升级日志

  • 1.1 添加了日志容错功能,在redis报错的同时,不影响其他程序运行
  • 1.2 升级spring-cache注解版功能
    • 可以将注解添加到任意Spring扫描的包下
  • 1.3 解决redis单机操作实现类在多线程下报错的原因。
    • 将redis错误日志的exception也放入到了error日志中
  • 1.4 解决问题:
    • 解决reids连接未释放的问题
    • redis配置添加密码配置
    • redis配置选择数据库的问题