通过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 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring学习笔记之RedisTemplate的配置与使用教程

    前言 Spring针对Redis的使用,封装了一个比较强大的Template以方便使用:之前在Spring的生态圈中也使用过redis,但直接使用Jedis进行相应的交互操作,现在正好来看一下RedisTemplate是怎么实现的,以及使用起来是否更加便利 I. 基本配置 1. 依赖 依然是采用Jedis进行连接池管理,因此除了引入 spring-data-redis之外,再加上jedis依赖,pom文件中添加 <dependency> <groupId>org.springfra

  • 详解springboot配置多个redis连接

    一.springboot nosql 简介 Spring Data提供其他项目,用来帮你使用各种各样的NoSQL技术,包括MongoDB, Neo4J, Elasticsearch, Solr, Redis,Gemfire, Couchbase和Cassandra.Spring Boot为Redis, MongoDB, Elasticsearch, Solr和Gemfire提供自动配置.你可以充分利用其他项目,但你需要自己配置它们. 1.1.Redis Redis是一个缓存,消息中间件及具有丰富

  • Springboot2.X集成redis集群(Lettuce)连接的方法

    前提:搭建好redis集群环境,搭建方式请看:https://www.jb51.net/article/143749.htm 1. 新建工程,pom.xml文件中添加redis支持 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2

  • 详解Redis开启远程登录连接

    今天使用jedis客户端api连接远程连接redis的时候,一直报错,如下: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect at redis.clients.jedis.Connection.connect(Connection.java:164) at redis.clients.jedis.BinaryClient.

  • spring整合redis以及使用RedisTemplate的方法

    需要的jar包 spring-data-Redis-1.6.2.RELEASE.jar jedis-2.7.2.jar(依赖 commons-pool2-2.3.jar) commons-pool2-2.3.jar spring-redis.xml 配置文件 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/sc

  • 在Java中使用redisTemplate操作缓存的方法示例

    背景 在最近的项目中,有一个需求是对一个很大的数据库进行查询,数据量大概在几千万条.但同时对查询速度的要求也比较高. 这个数据库之前在没有使用Presto的情况下,使用的是Hive,使用Hive进行一个简单的查询,速度可能在几分钟.当然几分钟也并不完全是跑SQL的时间,这里面包含发请求,查询数据并且返回数据的时间的总和.但是即使这样,这样的速度明显不能满足交互式的查询需求. 我们的下一个解决方案就是Presto,在使用了Presto之后,查询速度降到了秒级.但是对于一个前端查询界面的交互式查询来

  • RedisDesktopManager无法远程连接Redis的完美解决方法

    Linux环境:ubuntu16.04 Redis服务端版本:3.2.6 Redis客户端下载链接:https://redisdesktop.com/download 省略Linux系统安装Redis教程,网上安装教程很多:建议用tar.gz包安装 Redis官网tar.gz下载地址:wget http://xiazai.jb51.net/201803/yuanma/redis-3.2.6(jb51.net).rar 下载RedisDesktopManager客户端,输入服务器IP地址,端口(缺

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

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

  • Spring Boot整合Spring Cache及Redis过程解析

    这篇文章主要介绍了Spring Boot整合Spring Cache及Redis过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.安装redis a.由于官方是没有Windows版的,所以我们需要下载微软开发的redis,网址: https://github.com/MicrosoftArchive/redis/releases b.解压后,在redis根目录打开cmd界面,输入:redis-server.exe redis.wind

  • SpringBoot整合Lettuce redis过程解析

    首先解释一下Lettuce客户端: Lettuce 和 Jedis 的都是连接Redis Server的客户端程序.Jedis在实现上是直连redis server,多线程环境下非线程安全,除非使用连接池,为每个Jedis实例增加物理连接.Lettuce基于Netty的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问,同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例. 1.添加依赖 <dependenc

  • Spring session整合到Redis过程解析

    为何要用Spring-session 在传统单机web应用中,一般使用tomcat/jetty等web容器时,用户的session都是由容器管理.浏览器使用cookie中记录sessionId,容器根据sessionId判断用户是否存在会话session.这里的限制是,session存储在web容器中,被单台服务器容器管理. 但是网站主键演变,分布式应用和集群是趋势(提高性能).此时用户的请求可能被负载分发至不同的服务器,此时传统的web容器管理用户会话session的方式即行不通.除非集群或者

  • Python如何操作docker redis过程解析

    使用操作命令借助subprocess模块进行操作 #encoding:utf-8 import subprocess def cmd(command): subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8") subp.wait(2) if subp.poll() == 0: return subp.communicate() e

  • Rust 连接 SQLite 数据库的过程解析

    使用 Rust 语言连接操作 SQLite 数据库,我使用 rusqlite 这个 crate. 看例子: 首先,使用 cargo 创建一个 Rust 项目,然后添加依赖 rusqlite: 来到 main.rs,其余所有的代码都写在这里. 首先引入 rusqlite 相关的类型,并建立一个 Person struct: Person 有三个字段,id.name 和 data,其实本例中,我们只会用到前两个字段. 下面,编写一个用来创建数据库和 person 表的函数: 该函数会创建名为 dat

  • redis使用不当导致应用卡死bug的过程解析

    目录 top jstack 查看堆内存 执行thread命令 首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象 刚开始当测试抱怨环境响应慢的时候 ,我们重启一下应用,应用恢复正常,于是没做处理.但是后来问题出现频率越来越频繁,越来越多的同事开始抱怨,于是感觉代码可能有问题,开始排查. 首先发现开发的本地ide没有发现问题,应用卡死时候数据库,redis都正常,并且无特殊错误日志.开始怀疑是sandbox环境机器问题(测试环境本身就很脆!_!) 于是ssh上

  • springboot整合redis集群过程解析

    简介 在springboot使用搭建好的redis集群 添加redis和连接池依赖 <!--redis连接池 start--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--redis连接池 end--> <!--redis start-

  • Spring Boot 2和Redis例子实现过程解析

    这篇文章主要介绍了Spring Boot2发布与调用REST服务过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Redis是一个key-value数据库,支持存储的value类型包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).在Java中,使用较为广泛的客户端有Redisson.Jedis.Spring Data Redis模块默认使用Jedis. 开发

  • SpringBoot redis分布式缓存实现过程解析

    前言 应用系统需要通过Cache来缓存不经常改变得数据来提高系统性能和增加系统吞吐量,避免直接访问数据库等低速存储系统.缓存的数据通常存放在访问速度更快的内存里或者是低延迟存取的存储器,服务器上.应用系统缓存,通常有如下作用:缓存web系统的输出,如伪静态页面.缓存系统的不经常改变的业务数据,如用户权限,字典数据.配置信息等 大家都知道springBoot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群

随机推荐