springBoot2.*使用redis集群/单机方法

springboot1.x系列中,其中使用的是jedis,但是到了springboot2.x其中使用的是Lettuce。 此处springboot2.x,所以使用的是Lettuce
关于jedislettuce的区别:

  • Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server。
  • Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
  • Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
新建一个springboot工程,添加如下pom依赖。
org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2

【springBoot2.*使用redis集群/单机方法】application.yml配置一下redis服务器的地址(其中nodes为集群redis的参数 host为单机redis的参数)
#REDIS redis: cache: nodes: #-192.168.1.2:7001前面使用 - host: localhost:6379 password: maxIdle: minIdle: maxTotal: maxWaitMillis: 5000

redis配置类:
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashSet; import java.util.Set; @Configuration public class RedisConfiguration { @Value("${spring.redis.cache.nodes:}") private String nodes; @Value("${spring.redis.cache.host:}") private String host; @Value("${spring.redis.cache.password:}") private String password; @Value("${spring.redis.cache.maxIdle:}") private Integer maxIdle; @Value("${spring.redis.cache.minIdle:}") private Integer minIdle; @Value("${spring.redis.cache.maxTotal:}") private Integer maxTotal; @Value("${spring.redis.cache.maxWaitMillis:}") private Long maxWaitMillis; @Bean LettuceConnectionFactory lettuceConnectionFactory() { // 连接池配置 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxIdle(maxIdle == null ? 8 : maxIdle); poolConfig.setMinIdle(minIdle == null ? 1 : minIdle); poolConfig.setMaxTotal(maxTotal == null ? 8 : maxTotal); poolConfig.setMaxWaitMillis(maxWaitMillis == null ? 5000L : maxWaitMillis); LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(poolConfig) .build(); // 单机redis RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(); redisConfig.setHostName(host==null||"".equals(host)?"localhost":host.split(":")[0]); redisConfig.setPort(Integer.valueOf(host==null||"".equals(host)?"6379":host.split(":")[1])); if (password != null && !"".equals(password)) { redisConfig.setPassword(password); }// 哨兵redis // RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration(); // 集群redis /*RedisClusterConfiguration redisConfig = new RedisClusterConfiguration(); Set nodeses = new HashSet<>(); String[] hostses = nodes.split("-"); for (String h : hostses) { h = h.replaceAll("\\s", "").replaceAll("\n", ""); if (!"".equals(h)) { String host = h.split(":")[0]; int port = Integer.valueOf(h.split(":")[1]); nodeses.add(new RedisNode(host, port)); } } redisConfig.setClusterNodes(nodeses); // 跨集群执行命令时要遵循的最大重定向数量 redisConfig.setMaxRedirects(3); redisConfig.setPassword(password); */return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration); }@Bean public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(lettuceConnectionFactory); //序列化类 MyRedisSerializer myRedisSerializer = new MyRedisSerializer(); //key序列化方式 template.setKeySerializer(myRedisSerializer); //value序列化 template.setValueSerializer(myRedisSerializer); //value hashmap序列化 template.setHashValueSerializer(myRedisSerializer); return template; }static class MyRedisSerializer implements RedisSerializer {@Override public byte[] serialize(Object o) throws SerializationException { return serializeObj(o); }@Override public Object deserialize(byte[] bytes) throws SerializationException { return deserializeObj(bytes); }/** * 序列化 * @param object * @return */ private static byte[] serializeObj(Object object) { ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; try { baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(object); byte[] bytes = baos.toByteArray(); return bytes; } catch (Exception e) { throw new RuntimeException("序列化失败!", e); } }/** * 反序列化 * @param bytes * @return */ private static Object deserializeObj(byte[] bytes) { if (bytes == null){ return null; } ByteArrayInputStream bais = null; try { bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { throw new RuntimeException("反序列化失败!", e); } } } }上
现在就可以正常的使用redis了示例
注入:
@Autowired private RedisTemplate redisTemplate;

添加:
redisTemplate.opsForValue().set(key, value);

添加,设置过期时间:
redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);

获取:
Object o = redisTemplate.opsForValue().get(key);

删除:
redisTemplate.delete(key);


还可以根据自己需要编写一个类RedisService,方便以后使用
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.ResponseBody; import java.util.concurrent.TimeUnit; import static java.util.Objects.hash; @Service public class RedisService { @Autowired private RedisTemplate redis; /** * 添加 * @param key * @param value */ @ResponseBody public void set(String key,String value){ redis.opsForValue().set(key,value); }/** * 添加并设置一个过期时间 * @param key * @param value * @param timeout时间 * @param unit *TimeUnit.DAYS//天 *TimeUnit.HOURS//小时 *TimeUnit.MINUTES//分钟 *TimeUnit.SECONDS//秒 *TimeUnit.MILLISECONDS//毫秒 */ public void set(String key, String value, long timeout,TimeUnit unit){ redis.opsForValue().set(key,value,timeout,unit); } /** * 添加并设置一个过期时间默订秒 * @param key * @param value * @param timeout时间 秒 */ public void set(String key, String value, long timeout){ redis.opsForValue().set(key,value,timeout,TimeUnit.SECONDS); } /** * 将指定param的值设置为1,{@param param}会经过hash计算进行存储。 * * @param keybitmap结构的key * @param param 要设置偏移的key,该key会经过hash运算。 * @param value true:即该位设置为1,否则设置为0 * @return 返回设置该value之前的值。 */ public Boolean setBit(String key,String param,boolean value){ return redis.opsForValue().setBit(key,hash(param),value); } /** * 获取 * @param key */ public Object get(String key){ return redis.opsForValue().get(key); }/** * 删除 * @param key */ public void del(String key){ redis.delete(key); } /** * 获取key大小 * @param keybitmap结构的key */ public Long size(String key){ return redis.opsForValue().size(key); } }


注入:

@Autowired private RedisService redis; 添

添加:
redis.set("usename","NX",9); //到期时间 秒

获取:
redis.get("usename");




    推荐阅读