springboot 2.0 通过 jedis 集成Redis服务
Jedis是一个非常小而且理智的Redis java客户端。
Jedis被认为易于使用。
Jedis与redis 2.8.x,3.xx及以上*完全兼容。
*仍有一些新功能添加Redis 5在Jedis中丢失,如Streams。
支持以下所有redis功能:
- 排序
- 连接处理
- 在任何类型的值上运行的命令
- 对字符串值运行的命令
- 在哈希上运行的命令
- 在列表上运行的命令
- 在集合上运行的命令
- 在有序集上运行的命令
- 交易
- 流水线
- 发布/订阅
- 持久性控制命令
- 远程服务器控制命令
- 连接池
- 碎片(MD5,MurmurHash)
- 用于分片的键标签
- 使用流水线进行分片
- 使用流水线编写脚本
- Redis集群
导入依赖
因为 springboot2.0中默认是使用 Lettuce来集成Redis服务,spring-boot-starter-data-redis
默认只引入了 Lettuce
包,并没有引入 jedis
包支持。所以在我们需要手动引入 jedis
的包,并排除掉 lettuce
的包,pom.xml配置如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
application.properties配置
使用jedis的连接池
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=root
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-active=8
使用application.yml配置:
spring:
redis:
host: 192.168.122.123
port:
password:
timeout:
database:
pool:
max-active: 10
max-idle: 8
min-idle: 2
max-wait: 100
redis-two:
host: 192.168.122.124
port:
password:
timeout:
database:
pool:
max-active: 10
max-idle: 8
min-idle: 2
max-wait: 100
配置 JedisConnectionFactory
因为在 springoot 2.x版本中,默认采用的是 Lettuce实现的,所以无法初始化出 Jedis的连接对象 JedisConnectionFactory,所以我们需要手动配置并注入使用spring官方的
/**
* @Author kay三石
* @date:2019/7/1
* Jedis是一个社区驱动的连接器,
* 由Spring Data Redis模块通过org.springframework.data.redis.connection.jedis包支持。在最简单的形式中,Jedis配置如下所示
*/
@Configuration
public class Appconfig {
/**
* 标准配置
* @return
*/
// @Bean
// public JedisConnectionFactory redisConnectionFactory() {
// return new JedisConnectionFactory();
// }
/**
* 但是,对于生产用途,您可能需要调整主机或密码等设置,如以下示例所示:
*/
@Bean
public JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379);
return new JedisConnectionFactory(config);
}
}
redis连接失败,springboot2.x通过以上方式集成Redis并不会读取配置文件中的 spring.redis.host
等这样的配置,需要手动配置,如下:
@Configuration
public class RedisConfig2 {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedisTemplate<String, Serializable> redisTemplate(JedisConnectionFactory connectionFactory) {
RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
config.setPassword(RedisPassword.of(password));
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(config);
return connectionFactory;
}
}
通过以上方式就可以连接上 redis了,不过这里要提醒的一点就是,在springboot 2.x版本中 JedisConnectionFactory
设置连接的方法已过时
在 springboot 2.x
版本中推荐使用 RedisStandaloneConfiguration
类来设置连接的端口,地址等属性
然后是单元测试即可
Jedis集群,单机,连接池版
package com.kayleoi.springbootdataredis.jedis;
import java.util.List;
/**
* @Author kay三石
* @date:2019/7/1
* 使用jedis操作
*/
public interface JedisClient {
String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);
Boolean hexists(String key, String field);
List<String> hvals(String key);
Long del(String key);
}
package com.kayleoi.springbootdataredis.jedis;
import redis.clients.jedis.JedisCluster;
import java.util.List;
/**
* @Author kay三石
* @date:2019/7/1
* 使用jedis操作集群方式
*/
public class JedisClientCluster implements JedisClient {
private JedisCluster jedisCluster;
public JedisCluster getJedisCluster() {
return jedisCluster;
}
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
@Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
@Override
public String get(String key) {
return jedisCluster.get(key);
}
@Override
public Boolean exists(String key) {
return jedisCluster.exists(key);
}
@Override
public Long expire(String key, int seconds) {
return jedisCluster.expire(key, seconds);
}
@Override
public Long ttl(String key) {
return jedisCluster.ttl(key);
}
@Override
public Long incr(String key) {
return jedisCluster.incr(key);
}
@Override
public Long hset(String key, String field, String value) {
return jedisCluster.hset(key, field, value);
}
@Override
public String hget(String key, String field) {
return jedisCluster.hget(key, field);
}
@Override
public Long hdel(String key, String... field) {
return jedisCluster.hdel(key, field);
}
@Override
public Boolean hexists(String key, String field) {
return jedisCluster.hexists(key, field);
}
@Override
public List<String> hvals(String key) {
return jedisCluster.hvals(key);
}
@Override
public Long del(String key) {
return jedisCluster.del(key);
}
}
package com.kayleoi.springbootdataredis.jedis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
/**
* @Author kay三石
* @date:2019/7/1
* 使用jedis操作jedis连接池
*/
public class JedisClientPool implements JedisClient{
/**
*在不同的线程中使用相同的Jedis实例会发生奇怪的错误。但是创建太多的实现也不好因为这意味着会建立很多sokcet连接,
* 也会导致奇怪的错误发生。单一Jedis实例不是线程安全的。为了避免这些问题,可以使用JedisPool,
* JedisPool是一个线程安全的网络连接池。
* 可以用JedisPool创建一些可靠Jedis实例,可以从池中拿到Jedis的实例。这种方式可以解决那些问题并且会实现高效的性能.
*/
private JedisPool jedisPool;
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
@Override
public Boolean exists(String key) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
}
@Override
public Long expire(String key, int seconds) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public Long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public Long hset(String key, String field, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
}
@Override
public String hget(String key, String field) {
Jedis jedis = jedisPool.getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
}
@Override
public Long hdel(String key, String... field) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
}
@Override
public Boolean hexists(String key, String field) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.hexists(key, field);
jedis.close();
return result;
}
@Override
public List<String> hvals(String key) {
Jedis jedis = jedisPool.getResource();
List<String> result = jedis.hvals(key);
jedis.close();
return result;
}
@Override
public Long del(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.del(key);
jedis.close();
return result;
}
}
package com.kayleoi.springbootdataredis.jedis;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import java.util.HashSet;
import java.util.Set;
/**
* @Author kay三石
* @date:2019/7/1
*/
public class JedisTest {
/**
* 测试单机的jedis
* @throws Exception
*/
@Test
public void testJedis() throws Exception {
//创建一个连接Jedis对象,参数:host、port
Jedis jedis = new Jedis("localhost", 6379);
//直接使用jedis操作redis。所有jedis的命令都对应一个方法。
jedis.set("test123", "my first jedis test");
String string = jedis.get("test123");
System.out.println(string);
//关闭连接
jedis.close();
}
/**
* 测试jedis连接池形式
* @throws Exception
*/
@Test
public void testJedisPool() throws Exception {
//创建一个连接池对象,两个参数host、port
JedisPool jedisPool = new JedisPool("localhost", 6379);
//从连接池获得一个连接,就是一个jedis对象。
Jedis jedis = jedisPool.getResource();
//使用jedis操作redis
String string = jedis.get("test123");
System.out.println(string);
//关闭连接,每次使用完毕后关闭连接。连接池回收资源。
jedis.close();
//关闭连接池。
jedisPool.close();
}
/**
* 测试集群的方式
* @throws Exception
*/
@Test
public void testJedisCluster() throws Exception {
//创建一个JedisCluster对象。有一个参数nodes是一个set类型。set中包含若干个HostAndPort对象。
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.25.162", 7001));
nodes.add(new HostAndPort("192.168.25.162", 7002));
nodes.add(new HostAndPort("192.168.25.162", 7003));
nodes.add(new HostAndPort("192.168.25.162", 7004));
nodes.add(new HostAndPort("192.168.25.162", 7005));
nodes.add(new HostAndPort("192.168.25.162", 7006));
JedisCluster jedisCluster = new JedisCluster(nodes);
//直接使用JedisCluster对象操作redis。
jedisCluster.set("test", "123");
String string = jedisCluster.get("test");
System.out.println(string);
//关闭JedisCluster对象
jedisCluster.close();
}
}