Spring boot integrates redis (multiple data sources)

Posted by parkie on Sat, 19 Feb 2022 09:46:28 +0100

Official website: https://spring.io/projects/spring-data-redis

Spring Data Redis is a part of the spring data series. Redis can be easily configured and accessed from spring applications, and supports low-level and high-level abstract interfaces. You can see that spring data provides the following technical solutions:

There are already excellent Java Redis tool libraries such as Redis, redison and lattice on the market. Why Spring Data Redis?

  • Spring and Jedis provide a unified operation template library for spring and Jedis.
  • For the upper layer, developers can learn how to use Spring Data Redis without caring about the API operations of Jedis and lettue. Even in the future, if we want to migrate Redis access from Jedis to lattice, we don't need to make any changes.
  • springboot 2. Version x uses Lettce as the default connection pool and can switch to jedis.

Note: at present, Spring Data Redis only supports the internal encapsulation of Jedis and lattice, while Redisson is provided by redisson-spring-data To provide.

Note: for the use of jedis, see https://blog.csdn.net/liuxiao723846/article/details/86724124

Next, we will mainly introduce the use of spring data redis (redis stand-alone), and the redis cluster and redis sentinel will be introduced later.

1. Single data source

1)maven:

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

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <exclusions>
            <!--Remove right Lettuce Because Spring Boot priority of use Lettuce As Redis client -->
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- introduce Jedis Dependence, so Spring Boot Implementation pair Jedis Automated configuration of -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
</dependencies>

Note: lettuce is used by default in spring boot starter data redis. If jedis library is used, it needs to be exclude d and then manually imported into jedis.

2)redis.properties:

redis.host=localhost
redis.port=7395
redis.password=123
redis.timeout=600000
#  Redis database number, which is 0 by default 
redis.database=0

#Maximum idle number  
redis.maxIdle=300  
#The maximum number of database connections to the connection pool. If it is set to 0, it means unlimited. If it is jedis 2.4, use redis maxTotal  
#redis.maxActive=600  
#Controls how many jedis instances can be allocated to a pool to replace the above redis Maxactive. Use this attribute after jedis 2.4  
redis.maxTotal=1000  
#Maximum connection setup wait time. If this time is exceeded, an exception will be received. Set to - 1 for unlimited.  
redis.maxWaitMillis=1000  
#The minimum idle time of a connection defaults to 1800000 milliseconds (30 minutes)  
redis.minEvictableIdleTimeMillis=300000  
#The maximum number of connections released each time. The default is 3  
redis.numTestsPerEvictionRun=1024  
#The time interval of eviction scanning (MS). If it is negative, the eviction thread will not be run. The default is - 1  
redis.timeBetweenEvictionRunsMillis=30000  
#Whether to verify the connection before removing it from the pool. If the verification fails, remove the connection from the pool and try to remove another one  
redis.testOnBorrow=true  
#Check validity when idle. The default is false  
redis.testWhileIdle=true  

3)RedisConfig.java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
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.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@PropertySource("classpath:redis.properties")
public class RedisConfig {
    
    @Value("${redis.host}")
    private String host;
    @Value("${redis.port}")
    private Integer port;
    @Value("${redis.password}")
    private String pwd;
    @Value("${redis.timeout}")
    private Integer timeout;
    
    @Value("${redis.maxIdle}")
    private Integer maxIdle;
    @Value("${redis.maxTotal}")
    private Integer maxTotal;
    @Value("${redis.maxWaitMillis}")
    private Integer maxWaitMillis;
    @Value("${redis.minEvictableIdleTimeMillis}")
    private Integer minEvictableIdleTimeMillis;
    @Value("${redis.numTestsPerEvictionRun}")
    private Integer numTestsPerEvictionRun;
    @Value("${redis.timeBetweenEvictionRunsMillis}")
    private long timeBetweenEvictionRunsMillis;
    @Value("${redis.testOnBorrow}")
    private boolean testOnBorrow;
    @Value("${redis.testWhileIdle}")
    private boolean testWhileIdle;
    
    /**
     * JedisPoolConfig Connection pool
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);// Maximum idle number
        jedisPoolConfig.setMaxTotal(maxTotal);// Maximum number of database connections to the connection pool
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);// Maximum connection setup wait time
        jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);// The default minimum idle time for evicting connections is 1800000 milliseconds (30 minutes)
        // The maximum number of evictions per eviction check is 1/abs(n) if it is negative. The default is 3
        jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
        // The time interval of eviction scanning (MS). If it is negative, the eviction thread will not be run. The default is - 1
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        // Whether to verify the connection before removing it from the pool. If the verification fails, remove the connection from the pool and try to remove another one
        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        jedisPoolConfig.setTestWhileIdle(testWhileIdle);// Check validity when idle. The default is false
        return jedisPoolConfig;
    }
    
    /**
     * Link factory
     */
    @Bean
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
        JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory();
        JedisConnectionFactory.setPoolConfig(jedisPoolConfig);  
        JedisConnectionFactory.setHostName(host);  
        JedisConnectionFactory.setPort(port);  
        if (pwd != null && !pwd.equals("")) {
            JedisConnectionFactory.setPassword(pwd);  
        }
        JedisConnectionFactory.setTimeout(timeout);  
        return JedisConnectionFactory; 
    }

    /**
     * RedisTemplate
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);// The key adopts the serialization method of String
        template.setHashKeySerializer(stringRedisSerializer);// The key of hash is serialized by String

//        GenericJackson2JsonRedisSerializer jacksonSerializer = new GenericJackson2JsonRedisSerializer();
//        template.setValueSerializer(jacksonSerializer);// value is serialized by jackson
//        template. setHashValueSerializer(jacksonSerializer);//  The value of hash adopts jackson serialization
        
        template.setEnableTransactionSupport(true);// Open transaction
        template.setConnectionFactory(factory);// Set up link factory
        
        return template;
    }
}

explain:

  • If you need to set the serialization method of value in your code, you don't need to specify it in RedisConfig. (for example, some business codes are serialized according to json and some are serialized according to pb)
  • In spring data redis, the word is serialized with string, jackson and other methods

Note: if the key serialization method is not specified, it will be found that there will be more keys in redis, such as \ xac\xed\x00\x05t\x00. Therefore, it is best to specify the key serialization method as string.

4) Use:

@Service
public class TestService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    public String test1(String value) {
        redisTemplate.opsForValue().set("test_1",value);
        
        return (String)redisTemplate.opsForValue().get("test_1");
    }
    
    public String test2(String value) {
        User user = new User(99,value);
        byte[] serialize = SerializeUtil.serialize(user);
        
        redisTemplate.opsForValue().set("test_9",serialize);
        
        byte[] bytes = (byte[])redisTemplate.opsForValue().get("test_9");
        User obj = (User) SerializeUtil.unserialize(bytes);

        return obj.toString();
    }
}


//Serialization tool
public class SerializeUtil {
    public static byte[] serialize(Object object) {//serialize
        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) {
            System.out.println(e);
        }
        return null;
    }
 
    public static Object unserialize(byte[] bytes) {//Deserialization
        ByteArrayInputStream bais = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            System.out.println(e);
        }
        return null;
    }
}

2. Single data source 2

The annotation method is used above (springboot adopts config annotation by default to replace the bean declaration in application.xml). Next, we use the original spring application.xml XML configuration mode.

 

 

If the primary node is not specified for multiple data sources, the following error will be reported:

Parameter 0 of method redisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration required a single bean, but 2 were found:

 

 

 

 

Topics: Java