先看示例:
// 将验证码放入缓存,并设置自动过期时间 CacheUtils.put(CacheKey.PHONE_VERIFY_CODE.key(phone), code, 1, TimeUnit.HOURS); // 从缓存中获取验证码 String code = CacheUtils.get(CacheKey.PHONE_VERIFY_CODE.key(phone)); // 删除缓存 CacheUtils.del(CacheKey.PHONE_VERIFY_CODE.key(phone));缓存使用注意事项:
1、缓存尽量设置一个过期时间
2、相关联的数据尽量用redis的HashMap结构存储,这样主动删除所有的时候,不需要使用模糊删除,模糊查询效率比较低,很占CPU
3、缓存value尽量用JSON字符串存储,因为我们遇到一个坑,直接存储对象,当对象中某些实体类属性包路径改变的时候,原来的数据反序列会报错。
下面是一些配置和工具类:
RedisClusterConfig.java
import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.MapPropertySource; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; /** * * * @Description: redis集群配置 */ @Configuration @EnableRedisRepositories public class RedisClusterConfig { @Value("${spring.redis.cluster.nodes}") private String clusterNodes; @Value("${spring.redis.cluster.timeout}") private Long timeout; @Value("${spring.redis.cluster.max-redirects}") private int redirects; @Autowired private RedisPoolConfig redisPoolConfig; @Bean public RedisClusterConfiguration getClusterConfiguration() { Map<String, Object> config = new HashMap<String, Object>(); config.put("spring.redis.cluster.nodes", clusterNodes.trim()); config.put("spring.redis.cluster.timeout", timeout); config.put("spring.redis.cluster.max-redirects", redirects); return new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", config)); } @Bean(name = "jedisPoolConfig") public JedisPoolConfig getJedisPoolConfig(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(redisPoolConfig.getMaxTotal()); jedisPoolConfig.setMaxIdle(redisPoolConfig.getMaxIdle()); jedisPoolConfig.setMinIdle(redisPoolConfig.getMinIdle()); jedisPoolConfig.setMaxWaitMillis(redisPoolConfig.getMaxWaitMillis()); jedisPoolConfig.setTestOnBorrow(redisPoolConfig.getTestOnBorrow()); jedisPoolConfig.setTestWhileIdle(redisPoolConfig.getTestWhileIdle()); jedisPoolConfig.setTestOnReturn(redisPoolConfig.getTestOnReturn()); jedisPoolConfig.setBlockWhenExhausted(redisPoolConfig.getBlockWhenExhausted()); jedisPoolConfig.setNumTestsPerEvictionRun(redisPoolConfig.getNumTestsPerEvictionRun()); jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisPoolConfig.getTimeBetweenEvictionRunsMillis()); jedisPoolConfig.setMinEvictableIdleTimeMillis(redisPoolConfig.getMinEvictableIdleTimeMillis()); return jedisPoolConfig; } public @Bean RedisConnectionFactory connectionFactory(RedisClusterConfiguration redisClusterConfig, @Qualifier("jedisPoolConfig") JedisPoolConfig pooConfig) { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfig); jedisConnectionFactory.setPoolConfig(pooConfig); jedisConnectionFactory.setUsePool(true); jedisConnectionFactory.afterPropertiesSet(); return jedisConnectionFactory; } @Bean(name = "redisTemplate") public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<byte[], byte[]> template = new RedisTemplate<byte[], byte[]>(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } }RedisPoolConfig.java
import org.springframework.boot.context.properties.ConfigurationProperties; /** * redis主从连接池配置bean * * @author Lee * */ @ConfigurationProperties(value = "jedisPool") public class RedisPoolConfig extends AbstractSettings { /** * 缓存最大连接数 */ private Integer maxTotal; /** * 缓存最大空闲数 */ private Integer maxIdle; /** * 缓存最小空闲数 */ private Integer minIdle; /** * 最大等待空闲时间 */ private Integer maxWaitMillis; private Boolean testOnBorrow; private Boolean testWhileIdle; private Boolean testOnReturn; private Boolean blockWhenExhausted; private Integer numTestsPerEvictionRun; private Integer timeBetweenEvictionRunsMillis; private Integer softMinEvictableIdleTimeMillis; /** * 最小驱逐空闲时间 */ private Integer minEvictableIdleTimeMillis; public Integer getMinEvictableIdleTimeMillis() { return minEvictableIdleTimeMillis; } public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) { this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; } public Integer getMaxTotal() { return maxTotal; } public void setMaxTotal(Integer maxTotal) { this.maxTotal = maxTotal; } public Integer getMaxIdle() { return maxIdle; } public void setMaxIdle(Integer maxIdle) { this.maxIdle = maxIdle; } public Integer getMinIdle() { return minIdle; } public void setMinIdle(Integer minIdle) { this.minIdle = minIdle; } public Integer getMaxWaitMillis() { return maxWaitMillis; } public void setMaxWaitMillis(Integer maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; } public Boolean getTestOnBorrow() { return testOnBorrow; } public void setTestOnBorrow(Boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; } public Boolean getTestWhileIdle() { return testWhileIdle; } public void setTestWhileIdle(Boolean testWhileIdle) { this.testWhileIdle = testWhileIdle; } public Boolean getTestOnReturn() { return testOnReturn; } public void setTestOnReturn(Boolean testOnReturn) { this.testOnReturn = testOnReturn; } public Boolean getBlockWhenExhausted() { return blockWhenExhausted; } public void setBlockWhenExhausted(Boolean blockWhenExhausted) { this.blockWhenExhausted = blockWhenExhausted; } public Integer getNumTestsPerEvictionRun() { return numTestsPerEvictionRun; } public void setNumTestsPerEvictionRun(Integer numTestsPerEvictionRun) { this.numTestsPerEvictionRun = numTestsPerEvictionRun; } public Integer getTimeBetweenEvictionRunsMillis() { return timeBetweenEvictionRunsMillis; } public void setTimeBetweenEvictionRunsMillis( Integer timeBetweenEvictionRunsMillis) { this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; } public Integer getSoftMinEvictableIdleTimeMillis() { return softMinEvictableIdleTimeMillis; } public void setSoftMinEvictableIdleTimeMillis( Integer softMinEvictableIdleTimeMillis) { this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; } }pom.xml
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version><!--$NO-MVN-MAN-VER$--> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.6.RELEASE</version><!--$NO-MVN-MAN-VER$--> </dependency>application.properties
jedisPool.maxTotal=2048 jedisPool.maxIdle=200 jedisPool.minIdle=10 jedisPool.numTestsPerEvictionRun=1024 jedisPool.timeBetweenEvictionRunsMillis=30000 jedisPool.minEvictableIdleTimeMillis=-1 jedisPool.softMinEvictableIdleTimeMillis=10000 jedisPool.maxWaitMillis=1500 jedisPool.testOnBorrow=true jedisPool.testWhileIdle=true jedisPool.testOnReturn=false jedisPool.blockWhenExhausted=false #********************redis.cluster****************************************** spring.redis.cluster.nodes= spring.redis.cluster.timeout=20000 spring.redis.cluster.max-redirects=8CacheUtils.java
import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; import org.joda.time.DateTime; import org.joda.time.Seconds; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import com.tomtop.framework.common.exception.MessageException; @Component public class CacheUtils{ private static RedisTemplate<String,Serializable> redisTemplate; @Autowired public void setRedisTemplate( RedisTemplate<String, Serializable> redisTemplate) { CacheTools.redisTemplate = redisTemplate; } public static void put(String key, Serializable value) { if(!key.contains(":")){ throw MessageException.newMessageException("key需要缓存库名,比如lottery_:"); } redisTemplate.opsForValue().set(key, value); } public static void put(String key, String hashKey, Serializable value) { if(!key.contains(":")){ throw MessageException.newMessageException("key需要缓存库名,比如lottery_:"); } redisTemplate.opsForHash().put(key, hashKey, value); } public static void put(String key, Serializable value, long time, TimeUnit unit) { if(!key.contains(":")){ throw MessageException.newMessageException("key需要缓存库名,比如lottery_:"); } redisTemplate.opsForValue().set(key, value, time, unit); } @SuppressWarnings("unchecked") public static <T>T get(String key) { try{ return (T)redisTemplate.opsForValue().get(key); }catch(Exception e){ e.printStackTrace(); } return null; } @SuppressWarnings("unchecked") public static <T>T get(String key, String hashKey){ return (T) redisTemplate.opsForHash().get(key, hashKey); } public static void expireAt(String key, Date date){ int seconds = Seconds.secondsBetween(new DateTime(), new DateTime(date)).getSeconds(); redisTemplate.expire(key, seconds, TimeUnit.SECONDS); } public static void del(String key) { redisTemplate.delete(key); } /** * 次日凌晨时间过期 * @param key */ public static void expireAtMorrowZero(String key){ expireAt(key, morrowZero()); } /** * 次日凌晨时间 * */ public static Date morrowZero(){ Calendar c = Calendar.getInstance(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.MILLISECOND, 0); c.add(Calendar.DAY_OF_MONTH, 1); return c.getTime(); } }CacheKey.java
/** * 缓存key */ public enum CacheKey { /** * CART缓存公用前缀 */ PREFIX_CART("cart_:"), /** * ORDER缓存公用前缀 */ PREFIX_ORDER("order_:"), // -------------------------------------------------------------CART配置缓存key----------------------------------------------------- PHONE_VERIFY_CODE(PREFIX_CART+"phone_verify_code_#{phone}"), // 手机验证码 // -------------------------------------------------------------ORDER配置缓存key----------------------------------------------------- DYNAMIC_MSG_KEY(PREFIX_ORDER+"dynamic_msg_#{code}_#{spu}"), // 动态消息 ; private String name; private CacheKey(String name) { this.name = name; } public String getName() { return name; } public String key(Object ... args){ String result = name; for(Object arg : args){ if(arg!=null){ result = result.replaceFirst("#\\{\\w*\\}", String.valueOf(arg)); } } return result; } @Override public String toString() { return name; } }
