`
357029540
  • 浏览: 734933 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

通过RedisTemplate连接多个Redis

阅读更多

        在集群环境的情况下连接多个Redis数据库是很正常的情况,因为平时都是使用本地环境的单Redis情况比较多,在这里用代码总结一下连接多个数据库的情况(主要是不同ip,同一个ip的不通数据库修改不通地方即可),这里还是使用的springboot提供的spring-boot-starter-data-redis工具包,具体介绍如下:

      1.引入redis相关的jar

       

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

 

 

         2.在配置文件application.properties文件中设置redis相关配置,这里我使用了一个本地的redis数据库,一个远程的redis数据库,这里只假设了ip地址不同,其他的配置都相同:

 

       

#配置缓存redis
spring.redis.database=8
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.keytimeout=1000
spring.redis.timeout=0

#配置第二个redis数据库地址
spring.redis.host2=172.19.3.150

     3.添加RedisTemplate的Bean:

 

 

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author liaoyubo
 * @version 1.0 2017/8/1
 * @description
 */
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String hostName;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String passWord;
    @Value("${spring.redis.pool.max-idle}")
    private int maxIdl;
    @Value("${spring.redis.pool.min-idle}")
    private int minIdl;
    @Value("${spring.redis.database}")
    private int database;
    @Value("${spring.redis.keytimeout}")
    private long keytimeout;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.host2}")
    private String hostName2;

    /*@Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(hostName);
        factory.setPort(port);
        factory.setTimeout(timeout); //设置连接超时时间
        return factory;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
        template.afterPropertiesSet();
        return template;
    }
    private void setSerializer(StringRedisTemplate template) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }*/

    @Bean
    public RedisConnectionFactory redisConnectionFactory(){
        JedisPoolConfig poolConfig=new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdl);
        poolConfig.setMinIdle(minIdl);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setNumTestsPerEvictionRun(10);
        poolConfig.setTimeBetweenEvictionRunsMillis(60000);
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);
        jedisConnectionFactory.setHostName(hostName);
        if(!passWord.isEmpty()){
            jedisConnectionFactory.setPassword(passWord);
        }
        jedisConnectionFactory.setPort(port);
        jedisConnectionFactory.setDatabase(database);
        return jedisConnectionFactory;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory2(){
        JedisPoolConfig poolConfig=new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdl);
        poolConfig.setMinIdle(minIdl);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setNumTestsPerEvictionRun(10);
        poolConfig.setTimeBetweenEvictionRunsMillis(60000);
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);
        jedisConnectionFactory.setHostName(hostName2);
        if(!passWord.isEmpty()){
            jedisConnectionFactory.setPassword(passWord);
        }
        jedisConnectionFactory.setPort(port);
        jedisConnectionFactory.setDatabase(database);
        return jedisConnectionFactory;
    }

    @Bean(name = "redisTemplate1")
    public RedisTemplate<String, Object> redisTemplateObject() throws Exception {
        RedisTemplate<String, Object> redisTemplateObject = new RedisTemplate<String, Object>();
        redisTemplateObject.setConnectionFactory(redisConnectionFactory());
        setSerializer(redisTemplateObject);
        redisTemplateObject.afterPropertiesSet();
        return redisTemplateObject;
    }

    @Bean(name = "redisTemplate2")
    public RedisTemplate<String, Object> redisTemplateObject2() throws Exception {
        RedisTemplate<String, Object> redisTemplateObject = new RedisTemplate<String, Object>();
        redisTemplateObject.setConnectionFactory(redisConnectionFactory2());
        setSerializer(redisTemplateObject);
        redisTemplateObject.afterPropertiesSet();
        return redisTemplateObject;
    }



    private void setSerializer(RedisTemplate<String, Object> template) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setKeySerializer(template.getStringSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        //在使用String的数据结构的时候使用这个来更改序列化方式
        /*RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer );
        template.setValueSerializer(stringSerializer );
        template.setHashKeySerializer(stringSerializer );
        template.setHashValueSerializer(stringSerializer );*/

    }

}

 

      4.App启动类:

 

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author liaoyubo
 * @version 1.0 2017/7/31
 * @description
 */
@SpringBootApplication
public class App {

    public static void main(String [] args){
        SpringApplication.run(App.class);
    }

}

     5.测试多个Redis数据库连接:

 

 

import com.springRedis.App;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;


/**
 * @author liaoyubo
 * @version 1.0 2017/7/31
 * @description
 */

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class PipelineTest {

    @Autowired
    @Resource(name = "redisTemplate1")
    private RedisTemplate<String,Object> redisTemplate1;

    @Autowired
    @Resource(name = "redisTemplate2")
    private RedisTemplate<String,Object> redisTemplate2;

    @Test
    public void testPipeLine(){
        redisTemplate1.opsForValue().set("a",1);
        redisTemplate1.opsForValue().set("b",2);
        /*redisTemplate1.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                redisConnection.openPipeline();
                for (int i = 0;i < 10;i++){
                    redisConnection.incr("a".getBytes());
                }
                System.out.println("a:"+redisTemplate1.opsForValue().get("a"));
                redisTemplate1.opsForValue().set("c",3);
                for(int j = 0;j < 20;j++){
                    redisConnection.incr("b".getBytes());
                }
                System.out.println("b:"+redisTemplate1.opsForValue().get("b"));
                System.out.println("c:"+redisTemplate1.opsForValue().get("c"));
                redisConnection.closePipeline();
                return null;
            }
        });*/
        System.out.println("b:"+redisTemplate1.opsForValue().get("b"));
        System.out.println("a:"+redisTemplate1.opsForValue().get("a"));

        redisTemplate2.opsForValue().set("m",5);
        redisTemplate2.opsForValue().set("n",6);
        System.out.println("m:"+redisTemplate2.opsForValue().get("m"));
        System.out.println("n:"+redisTemplate2.opsForValue().get("n"));
    }

            以上就是连接2个Redis数据库的例子,在这里还有一个需要注意的是不能将

private RedisTemplate<String,Object> redisTemplate1

          代码中的redisTemplate1修改为redisTemplate,因为这个redisTemplate可能是程序中默认的全局变量,具体的代码逻辑没有去查看,如果修改为了redisTemplate的话会出现以下错误:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<?, ?>' available: expected single matching bean but found 2: redisTemplate1,redisTemplate2
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
	... 33 more

         如果在设置RedisConnectionFactory的连接工厂时,一定要保留一个如下的代码:

public RedisConnectionFactory redisConnectionFactory()

         否则会出现以下错误:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available: expected single matching bean but found 2: redisConnectionFactory1,redisConnectionFactory2
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
	... 47 more

 

 

 

分享到:
评论

相关推荐

    通过RedisTemplate连接多个Redis过程解析

    "通过RedisTemplate连接多个Redis过程解析" 本文主要介绍了通过RedisTemplate连接多个Redis过程解析,详细介绍了使用SpringBoot提供的spring-boot-starter-data-redis工具包连接多个Redis数据库的过程。 首先,在...

    redisTemplate封装成redisUtils和分布式锁实现

    然后,我们创建一个RedisConfig配置类,初始化RedisTemplate: ```java @Configuration public class RedisConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { ...

    SpringBoot2.X整合redis连接lettuce增强版本,支持多数据库切换,主从集群,哨兵

    基于`SpringBoot2.X + Lettuce`实现Redis集成和多库实时切换是一个非常实用的项目。以下是对该项目的一些重点说明: 1. **项目概述** 该项目的主要目标是在`SpringBoot`...可以配置多个Redis实例,用于实现多库切换。

    redis集群连接及工具类DEMO

    Redis集群采用分片(Sharding)策略来分布数据,将键空间划分为多个槽(Slots),每个节点负责一部分槽。当客户端对某个键进行操作时,会根据槽的映射规则确定操作的目标节点,从而实现负载均衡。 2. **Spring集成...

    Springmvc多模块集成多数据源及redis

    通过定义多个`DataSource`实例,每个实例对应一个数据源,然后创建一个`AbstractRoutingDataSource`子类,重写`determineCurrentLookupKey`方法来根据业务逻辑动态选择当前要使用的数据源。这样,我们就可以在代码中...

    springboot连接redis简单示例

    Redis是一个开源的、基于键值对的数据存储系统,常用于缓存、消息队列和数据持久化等多个场景。而Spring Boot是Spring框架的一个简化版,它提供了开箱即用的特性,使得构建微服务应用变得更为便捷。 首先,为了在...

    监听redis过期key,做对应业务处理

    然后,定义一个RedisTemplate bean,用于操作Redis。在Spring Boot自动配置的基础上,我们通常不需要手动创建这个bean,但可以根据需要自定义配置: ```java @Configuration public class RedisConfig { @Bean ...

    SpringBoot使用注解实现 Redis 数据库的切换.zip

    这样,我们就能灵活地在多个Redis数据库之间切换,满足不同场景的需求。在实际开发中,还可以结合Spring的其他特性,如AOP(面向切面编程)来实现更复杂的逻辑,比如在特定的请求条件下自动切换数据库。

    redis(哨兵模式配置) + springmvc

    哨兵系统由多个哨兵节点组成,它们之间通过 gossip 协议交换信息,共同维护整个集群的健康状态。 配置哨兵模式主要包括以下几个步骤: 1. **启动哨兵节点**:在每个哨兵节点的配置文件中,需要指定要监视的主节点...

    redis 哨兵(sentinel)与springboot集成实战-redis-sentinel.zip

    Redis Sentinel系统通常由多个Sentinel节点组成,它们共同监控主Redis服务器和其备份服务器(Slaves)。Sentinel节点之间通过Gossip协议进行通信,共享状态信息,并对主服务器的健康状况进行检查。当主服务器故障时...

    Spring3.0整合redis相关jar

    6. **事务支持**: 虽然Redis本身不支持事务,但Spring Data Redis提供了一种模拟事务的机制,可以控制多个Redis操作的原子性。 通过以上步骤,你可以在Spring 3.0应用中成功集成Redis。需要注意的是,随着Spring和...

    redis客户端连接、spring boot整合、分布式锁.zip

    然后通过 `@Autowired` 注解注入 `StringRedisTemplate` 或 `RedisTemplate` 对象,这两个模板类提供了操作 Redis 的便捷方法。例如: ```yaml spring: redis: host: localhost port: 6379 ``` ```java @...

    springboot-redis事务

    在实际应用中,如果需要更高级别的事务管理,比如跨多个键的操作,可能需要借助分布式事务解决方案,如Seata、TCC(Try-Confirm-Cancel)模式或者Saga模式。这些方案可以在微服务架构中提供分布式事务的支持,但实现...

    RedisCluster集群(Spring访问Redis)

    Redis Cluster是Redis官方提供的分布式解决方案,它将数据分片到多个节点上,每个节点存储一部分数据,从而实现了水平扩展。Redis Cluster采用了无中心的设计,所有节点彼此通信,共同维护整个集群的状态。 ### 2. ...

    redistemplate

    3. **主从复制**:通过复制,Redis可以创建多个从节点来分担负载,提升读取性能,同时为主节点提供故障转移的备份。 4. **哨兵系统(Sentinel)**:Redis Sentinel是一个高可用性解决方案,它可以监控主从节点的...

    Spring整合Redis哨兵

    `RedisTemplate`是Spring Data Redis提供的一个工具类,用于执行各种Redis操作。例如,我们可以通过`opsForValue()`方法进行键值对的操作,`opsForHash()`处理哈希表,`opsForSet()`处理集合等。 4. **Redis事务...

    redis cluster spring整合代码

    Redis Cluster通过将数据分割成多个槽(slots)并分布在多个节点之间来实现数据的分布式存储,每个节点负责一部分槽,从而达到水平扩展的目的。 **Spring与Redis的整合** Spring框架提供了一套完善的集成Redis的...

    搭建springboot与redis集群关联操作.doc

    * 集群模式:将多个 Redis 服务器组成一个集群,以提高系统的可扩展性和高可用性。 七、结论 本文档详细讲解了如何搭建 Spring Boot 与 Redis 集群的关联操作,包括搭建 Redis 集群、Spring Boot 配置调用 Redis、...

    redis+spring jedis方式

    【Redis与Spring集成】 Redis,一个高性能的键值对存储系统,常被用作数据库、缓存和消息中间件。其高效性能得益于内存存储和...不过,随着Spring Data Redis的更新,建议考虑使用更新的版本以获得更多的特性和改进。

    springcloud部署redis集群

    Redis集群通过数据分片(Sharding)技术,将数据分散存储在多个节点上,每个节点只负责一部分数据,从而实现数据的水平扩展。每个节点都是独立的Redis实例,可以处理读写请求。集群中的节点之间通过Gossip协议进行...

Global site tag (gtag.js) - Google Analytics