springboot项目中连接2个redis实例
- 基于JDK1.8
- Maven
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.1.5.RELEASE</version> </dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0-m4</version>
</dependency>
配置文件application.properties
############### Redis配置 start############### #业务数据redis配置 spring.redis.jedis.pool.max-active=50 spring.redis.jedis.pool.max-wait=15 spring.redis.jedis.pool.max-idle=50 spring.redis.jedis.pool.min-idle=0 spring.redis.timeout=15 spring.redis.database=1 #spring.redis.host=192.169.1.71 #spring.redis.port=6379 spring.redis.password=123456 #如果是集群,不需要配置host和port,请配置cluster spring.redis.cluster.nodes=192.169.1.71:7001,192.169.1.71:7002,192.169.1.71:7003,192.169.1.71:7004,192.169.1.71:7005,192.169.1.71:7006 spring.redis.cluster.max-redirects=3 #缓存数据redis配置 spring.redis2.jedis.pool.max-active=50 spring.redis2.jedis.pool.max-wait=5 spring.redis2.jedis.pool.max-idle=50 spring.redis2.jedis.pool.min-idle=0 spring.redis2.timeout=5 spring.redis2.database=1 spring.redis2.host=192.169.1.71 spring.redis2.port=6379 spring.redis2.password=123456 #如果是集群,不需要配置host和port,请配置cluster
#spring.redis2.cluster.nodes=192.169.1.71:7001,192.169.1.71:7002,192.169.1.71:7003,192.169.1.71:7004,192.169.1.71:7005,192.169.1.71:7006 #spring.redis2.cluster.max-redirects=3 ################ Redis配置 end###############
可以看到上面有两个redis。 一个是存业务数据的redis称之为redis1,一个是存缓存数据的redis称之为redis2
要连接两个redis实例需要重写两个RedisConnectionFactory
redis1
RedisConfig.java (配置类,自定义工厂RedisConnectionFactory,创建RedisTemplate)
package com.montnets.email.middleware.redis; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.montnets.email.specmailgate.util.StrUtil; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.EnableCaching; 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.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.stereotype.Component; import java.time.Duration; import java.util.HashMap; import java.util.Map; /** * redis 配置类 * @author Void * @date 2019/5/25 11:34 * @description:RedisConnectionFactory、RedisTemplate会自动装配 * @version v2.0.0 * @see {@link org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration} */ @Configuration @EnableCaching @Component public class RedisConfig { //最大活跃数 @Value("${spring.redis.jedis.pool.max-active:8}") private int maxActive; //最大等待数 @Value("${spring.redis.jedis.pool.max-wait:-1}") private int maxWait; //最大核心线程数 @Value("${spring.redis.jedis.pool.max-idle:8}") private int maxIdle; //最小核心线程数 @Value("${spring.redis.jedis.pool.min-idle:0}") private int minIdle; //redis连接的超时时长 @Value("${spring.redis.timeout:5}") private int timeOut; //redis连接的库 @Value("${spring.redis.database:0}") private int database; //节点配置 @Value("${spring.redis.cluster.nodes:#{null}}") private String nodes; //最大连接转移数 @Value("${spring.redis.cluster.max-redirects:3}") private int maxRedirects; //单节点情况下redis的ip @Value("${spring.redis.host:#{null}}") private String host; //单节点情况下redis的端口 @Value("${spring.redis.port:#{null}}") private Integer port; //redis的连接密码 @Value("${spring.redis.password:#{null}}") private String password; /** * 创建redisTemplate * 所有序列化k/v都会默认使用{@link org.springframework.data.redis.serializer.JdkSerializationRedisSerializer} * 默认的序列化类用使用byte数组进行存储, 在使用redis可视化客户端看到都是乱码不直观 * 使用StringRedisSerializer序列化Key, Jackson2JsonRedisSerializer序列化值, 可以观察到对象结构层次 * * * @return */ @Bean @Qualifier("redisTemplate") public RedisTemplate<String, Object> redisTemplate() { Jackson2JsonRedisSerializer<Object> valueSerializer = jackson2JsonRedisSerializer(); StringRedisSerializer keySerializer = new StringRedisSerializer(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory()); redisTemplate.setKeySerializer(keySerializer); redisTemplate.setValueSerializer(valueSerializer); redisTemplate.setHashKeySerializer(keySerializer); redisTemplate.setHashValueSerializer(valueSerializer); return redisTemplate; } /** * 定义序列化类 * * @return */ public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } /** * 连接配置 * @return */ @Bean public RedisConnectionFactory connectionFactory() { Map<String, Object> source = new HashMap<String, Object>(); RedisClusterConfiguration redisClusterConfiguration; RedisStandaloneConfiguration redisStandaloneConfiguration; //连接池配置 GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxTotal(maxActive); genericObjectPoolConfig.setMaxWaitMillis(maxWait); genericObjectPoolConfig.setMaxIdle(maxIdle); genericObjectPoolConfig.setMinIdle(minIdle); //redis客户端配置 LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(). commandTimeout(Duration.ofSeconds(timeOut)); builder.poolConfig(genericObjectPoolConfig); LettuceClientConfiguration lettuceClientConfiguration = builder.build(); //集群模式 if(nodes !=null){ source.put("spring.redis.cluster.nodes", nodes); source.put("spring.redis.cluster.max-redirects", maxRedirects); redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); if(!StrUtil.isEmpty(password)){ redisClusterConfiguration.setPassword(password); } //根据配置和客户端配置创建连接 LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration,lettuceClientConfiguration); // lettuceConnectionFactory .afterPropertiesSet(); return lettuceConnectionFactory; }else{ //单机模式 redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port); redisStandaloneConfiguration.setDatabase(database); if(!StrUtil.isEmpty(password)){ redisStandaloneConfiguration.setPassword(password); } //根据配置和客户端配置创建连接工厂 LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration); // lettuceConnectionFactory .afterPropertiesSet(); return lettuceConnectionFactory; } } }
RedisService.java (redis服务类,提供操作redis的方法,装配redis1的redistemplate)
package com.montnets.email.middleware.redis; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.*;import org.springframework.stereotype.Component;/** * redis缓存调用的Java方法 * @author chenlinyan * @date 2019/5/25 11:34 * @description:RedisTemplate会自动装配 * @version v2.0.0 * @see {@link org.springframework.boot.autoconfigure.data.redis} */ @Slf4j @Component public class RedisService { @Autowired @Qualifier("redisTemplate") private RedisTemplate redisTemplate;
/** * 写入redis缓存 * @param key 键 * @param value value * @return */ public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { log.error("set key value error", e); } return result; }
/** * 删除指定key * @param key * @return */ public boolean delete(String key){ return redisTemplate.delete(key); } }
redis2
Redis2Config.java (配置类,自定义工厂RedisConnectionFactory,创建RedisTemplate)
package com.montnets.email.middleware.redis; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.montnets.email.specmailgate.util.StrUtil; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; 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.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.stereotype.Component; import java.time.Duration; import java.util.HashMap; import java.util.Map; /** * @author :Void * @date :2019-09-17 09:21 * @description:另一个redis的配置 * @version: v1.0.0.23 */ @Component @Configuration @EnableCaching public class Redis2Config { //最大活跃数 @Value("${spring.redis2.jedis.pool.max-active:8}") private int maxActive; //最大等待数 @Value("${spring.redis2.jedis.pool.max-wait:-1}") private int maxWait; //最大核心线程数 @Value("${spring.redis2.jedis.pool.max-idle:8}") private int maxIdle; //最小核心线程数 @Value("${spring.redis2.jedis.pool.min-idle:0}") private int minIdle; //redis连接的超时时长 @Value("${spring.redis2.timeout:5}") private int timeOut; //redis连接的库 @Value("${spring.redis2.database:0}") private int database; //节点配置 @Value("${spring.redis2.cluster.nodes:#{null}}") private String nodes; //最大连接转移数 @Value("${spring.redis2.cluster.max-redirects:3}") private int maxRedirects; //单节点情况下redis的ip @Value("${spring.redis2.host:#{null}}") private String host; //单节点情况下redis的端口 @Value("${spring.redis2.port:#{null}}") private Integer port; //redis的连接密码 @Value("${spring.redis2.password:#{null}}") private String password; /** * 创建redisTemplate连接模板 * * @return */ @Primary @Bean @Qualifier("redisTemplate2") public RedisTemplate<String, Object> redisTemplate2() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory2()); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(this.jackson2JsonRedisSerializer2()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(this.jackson2JsonRedisSerializer2()); return redisTemplate; } /** * k-v的序列化 * * @return */ @Bean public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer2() { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } /** * 连接配置 * * @return */ @Primary @Bean public RedisConnectionFactory connectionFactory2() { Map<String, Object> source = new HashMap<String, Object>(); RedisClusterConfiguration redisClusterConfiguration; RedisStandaloneConfiguration redisStandaloneConfiguration; //连接池配置 GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxTotal(maxActive); genericObjectPoolConfig.setMaxWaitMillis(maxWait); genericObjectPoolConfig.setMaxIdle(maxIdle); genericObjectPoolConfig.setMinIdle(minIdle); //redis客户端配置 LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(). commandTimeout(Duration.ofSeconds(timeOut)); builder.poolConfig(genericObjectPoolConfig); LettuceClientConfiguration lettuceClientConfiguration = builder.build(); //集群模式 if(nodes !=null){ source.put("spring.redis.cluster.nodes", nodes); source.put("spring.redis.cluster.max-redirects", maxRedirects); redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); if(!StrUtil.isEmpty(password)){ redisClusterConfiguration.setPassword(password); } //根据配置和客户端配置创建连接工厂 LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisClusterConfiguration,lettuceClientConfiguration); // lettuceConnectionFactory .afterPropertiesSet(); return lettuceConnectionFactory; }else{ //单机模式 redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port); redisStandaloneConfiguration.setDatabase(database); if(!StrUtil.isEmpty(password)){ redisStandaloneConfiguration.setPassword(password); } //根据配置和客户端配置创建连接 LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration); // lettuceConnectionFactory .afterPropertiesSet(); return lettuceConnectionFactory; } } }
Redis2Service.java (redis服务类,提供操作redis的方法,装配redis1的redistemplate)
package com.montnets.email.middleware.redis; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; /** * redis缓存调用的Java方法 * @author chenlinyan * @date 2019/5/25 11:34 * @description:RedisTemplate会自动装配 * @version v2.0.0 * @see {@link org.springframework.boot.autoconfigure.data.redis} */ @Slf4j @Component public class Redis2Service { @Autowired @Qualifier("redisTemplate2") private RedisTemplate redisTemplate; /** * 写入redis缓存 * @param key 键 * @param value value * @return */ public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { log.error("set key value error", e); } return result; } /** * 删除指定key * @param key * @return */ public boolean delete(String key){ return redisTemplate.delete(key); } }
测试类
package com.montnets.test; import com.montnets.email.MailgateApplication; import com.montnets.email.middleware.redis.Redis2Service; import com.montnets.email.middleware.redis.RedisService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; /** * @author chenlinyan * @date 2019/6/17 10:35 * @version v2.0.0 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = MailgateApplication.class) public class AppTest { @Resource private RedisService redisService; @Resource private Redis2Service redis2Service; @Test public void testSave() { //存数据到redis1中 redisService.set("redis1","1111"); //存数据到redis2中 redis2Service.set("redis2","2222"); } }
参考地址
LettuceConnectionFactory多配置,及配置原理详解 https://blog.csdn.net/qq_42394457/article/details/94493027
Spring boot配置多个Redis数据源操作实例 https://www.jianshu.com/p/c79b65b253fa