Spring boot integrates Redis with multiple data sources

Spring boot integrates Redis

In fact, the method is similar to the single data. Let's write it here

Multi data source consolidation

I Complete profile

# Spring configuration
spring:
  # resource information 
  messages:
    # Internationalization resource file path
    basename: i18n/messages
  profiles:
    active: druid
  # File upload
  servlet:
     multipart:
       # Single file size
       max-file-size:  10GB
       # Set the total uploaded file size
       max-request-size:  20GB
  # Service module
  devtools:
    restart:
      # Hot deployment switch
      enabled: true
  # redis configuration
  redis:
    # address
    host: localhost
    # Port, 6379 by default
    port: 6379
    # Database index
    database: 0
    # password
    password:
    # Connection timeout
    timeout: 10s
    lettuce:
      pool:
        # Minimum free connections in connection pool
        min-idle: 0
        # Maximum free connections in the connection pool
        max-idle: 8
        # Maximum number of database connections to the connection pool
        max-active: 8
        # #Maximum blocking wait time of connection pool (negative value indicates no limit)
        max-wait: -1ms
  # The second set of redis data sources
  redis2:
    # address
    host: 172.21.10.62
    # Port, 6379 by default
    port: 6379
    # Database index
    database: 0
    # password
    password: Dfd3D@
    # Connection timeout
    timeout: 10s
    lettuce:
      pool:
        # Minimum free connections in connection pool
        min-idle: 0
        # Maximum free connections in the connection pool
        max-idle: 8
        # Maximum number of database connections to the connection pool
        max-active: 8
        # #Maximum blocking wait time of connection pool (negative value indicates no limit)
        max-wait: -1ms

The normal format is also OK, because it is to be read from the configuration file, and the format can be customized
For example:

# Customized Redis configuration
redis:
  firstRedisName:
    # address
    host: localhost
    # Port, 6379 by default
    port: 6379
    # Database index
    database: 0
    # password
    password:

  SecondRedisName:
    # address
    host: localhost
    # Port, 6379 by default
    port: 6379
    # Database index
    database: 0
    # password
    password:

Timeout can be added or not, because it may be unified and can be written dead

II Write configuration class

  1. Create a configuration class that inherits from CachingConfigurerSupport
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {}
  1. Load data from configuration file

For example:

  //1. Load redis1 data from the configuration file
  @Value("${spring.redis.host}")
  private String redisHost;
  @Value("${spring.redis.port}")
  private String redisPort;
  @Value("${spring.redis.password}")
  private String redisPassword;
  //2. Load redis2 data from the configuration file
  @Value("${spring.redis2.host}")
  private String redis2Host;
  @Value("${spring.redis2.port}")
  private String redis2Port;
  @Value("${spring.redis2.password}")
  private String redis2Password;
  1. Configure connection information, which can be written to the configuration file
  //3. Connection information
  //Maximum number of free connections
  private static final int MAX_IDLE = 200;
  //maximum connection
  private static final int MAX_TOTAL = 1024;
  //Establish maximum wait time
  private static final long MAX_WAIT_MILLIS = 10 * 1000;
  1. Connection pool configuration
  //4. Connection pool configuration
  public JedisPoolConfig jedisPoolConfig() {
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    //1. Configure the maximum number of idle connections
    jedisPoolConfig.setMaxIdle(MAX_IDLE);
    //2. Configure the maximum number of connections
    jedisPoolConfig.setMaxTotal(MAX_TOTAL);
    //3. Configure the maximum waiting time
    jedisPoolConfig.setMaxWaitMillis(MAX_WAIT_MILLIS);
    //4. Testonmirror: if true (false by default), when the application applies for a connection to the connection pool, the connection pool will judge whether the connection is available.
    jedisPoolConfig.setTestOnBorrow(false);
    return jedisPoolConfig;
  }
  1. Configuration factory
  //5. Configuration plant
  public RedisConnectionFactory redisConnectionFactory() {
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(redis2Host);
    jedisConnectionFactory.setPort(Integer.parseInt(redis2Port));
    if (StringUtils.isNotEmpty(redis2Password)) {
      jedisConnectionFactory.setPassword(redis2Password);
    }
    //Configure which library to connect to Redis. The default is the first
    if (0 != 0) {
      jedisConnectionFactory.setDatabase(0);
    }
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    return jedisConnectionFactory;
  }
  1. Create Redis template
  @Bean(name = "againRedisTemplate")
  public RedisTemplate<String,Object> aredisTemplate(){
    RedisTemplate<String,Object> stringRedisTemplate = new RedisTemplate<>();
    RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
    //1. Set the serializer of Jason
    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);
    //2. Set up factory
    stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory());
    //3. Set the serializer of the key
    stringRedisTemplate.setKeySerializer(stringRedisSerializer);
//    stringRedisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    //4. Set the serializer of Value (I set it to String type here)
    stringRedisTemplate.setValueSerializer(stringRedisSerializer);
    //5. Set Hash, which is of type Json
    stringRedisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    return stringRedisTemplate;
  }

The @ Bean(name = "againRedisTemplate") here will be used later

About ObjectMapper, comments from him

ObjectMapper provides the function of reading and writing JSON, which can be read and written with basic POJO (Plain Old Java Objects) or common JSON tree model (JsonNode), as well as the related functions for performing conversion. IT is also highly customizable, which can not only handle different styles of JSON content, but also support more advanced object concepts, such as polymorphism and object identity. ObjectMapper also acts as a factory for the more advanced ObjectReader and ObjectWriter classes. The mapper (and ObjectReader S, IT build of ObjectWriter) will use instances JsonParser and JsonGenerator to implement actual read / JSON writing. Note that although most read / write methods are exposed through this class, some functions are only through ObjectReader and ObjectWriter: specifically, reading / writing longer value sequences can only be through ObjectReader.readValues(InputStream) And ObjectWriter writeValues(OutputStream) . The simplest usage is the following form:
final ObjectMapper mapper = new ObjectMapper(); // can use static singleton, inject: just make sure to reuse!
MyValue value = new MyValue();
// ... and configure
File newState = new File("my-stuff.json");
mapper.writeValue(newState, value); // writes JSON serialization of MyValue instance
// or, read
MyValue older = mapper.readValue(new File("my-older-stuff.json"), MyValue.class);

// Or if you prefer JSON Tree representation:
JsonNode root = mapper.readTree(newState);
// and find values by, for example, using a JsonPointer expression:
int age = root.at("/personal/age").getValueAsInt();
The main transformation API is defined in ObjectCodec, so the implementation details of this class do not need to be exposed to the stream parser and generator classes. However, use through ObjectCodec is usually only applicable when it is impossible (from the Streaming API) or undesirable (when relying only on the Streaming API) to rely on ObjectMapper.
Mapper instances are fully thread safe, provided that all configuration of the instance occurs before any read or write call. If the configuration of the mapper instance is modified after the first use, the change may or may not take effect, and the configuration call itself may fail. If you need to use different configurations, you have two main possibilities:
Construct and use ObjectReader to read and ObjectWriter to write. Both types are completely immutable, and you are free to create new instances with different configurations using the ObjectMapper factory method or the reader / ObjectMapper itself. Building new ObjectReader and ObjectWriter is a very lightweight operation, so it is usually suitable to create them on a per call basis as needed to configure the optional indentation of JSON.
If a specific type of configurable ObjectWriter cannot be obtained through ObjectReader and ObjectWriter, You may need to use more than one ObjectMapper instead (for example, you cannot change the mixed annotation immediately; or, a set of custom (DE) serializers). To help use this usage, you may need to use the method copy() to create a clone of the mapper with a specific configuration and allow the copied instance to be configured before use. Note that copy operations are as expensive as building new ObjectMapper instances: if possible, you should still pool and reuse mappers if you intend to use them for multiple operations.
Note on caching: the root deserializer is always cached, And access with complete (generic aware) type information. This is different from the cache of reference types, which is more restricted and completed only for a subset of all deserializer types. The main reason for the difference is that no reference is passed in at the root level (therefore, there are no reference properties, no reference information or comments to generate different deserializers), and the performance impact is the greatest at the root level (because it essentially caches the complete diagram of the deserializer involved).
Security considerations: if used with untrusted content (content generated by untrusted external parties), there is a potential security risk in using the "default type" function (see enableDefaultTyping()). If so, you may need to build a custom TypeResolverBuilder implementation to limit possible types for instantiation (using setDefaultTyping).

  1. use

First statement

    @Resource(name = "againRedisTemplate")
    RedisTemplate<String, Object> testRedisTemplate;

You can use it

        String hello = (String) testRedisTemplate.opsForValue().get("hello");
        System.out.println(hello);
        return AjaxResult.success(hello);
  1. All codes
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
  //1. Load redis1 data from the configuration file
  @Value("${spring.redis.host}")
  private String redisHost;
  @Value("${spring.redis.port}")
  private String redisPort;
  @Value("${spring.redis.password}")
  private String redisPassword;
  //2. Load redis2 data from the configuration file
  @Value("${spring.redis2.host}")
  private String redis2Host;
  @Value("${spring.redis2.port}")
  private String redis2Port;
  @Value("${spring.redis2.password}")
  private String redis2Password;

  //3. Connection information
  //Maximum number of free connections
  private static final int MAX_IDLE = 200;
  //maximum connection
  private static final int MAX_TOTAL = 1024;
  //Establish maximum wait time
  private static final long MAX_WAIT_MILLIS = 10 * 1000;

  //4. Connection pool configuration
  public JedisPoolConfig jedisPoolConfig() {
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    //1. Configure the maximum number of idle connections
    jedisPoolConfig.setMaxIdle(MAX_IDLE);
    //2. Configure the maximum number of connections
    jedisPoolConfig.setMaxTotal(MAX_TOTAL);
    //3. Configure the maximum waiting time
    jedisPoolConfig.setMaxWaitMillis(MAX_WAIT_MILLIS);
    //4. Testonmirror: if true (false by default), when the application applies for a connection to the connection pool, the connection pool will judge whether the connection is available.
    jedisPoolConfig.setTestOnBorrow(false);
    return jedisPoolConfig;
  }
  //5. Configuration plant
  public RedisConnectionFactory redisConnectionFactory() {
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setHostName(redis2Host);
    jedisConnectionFactory.setPort(Integer.parseInt(redis2Port));
    if (StringUtils.isNotEmpty(redis2Password)) {
      jedisConnectionFactory.setPassword(redis2Password);
    }
    //Configure which library to connect to Redis. The default is the first
    if (0 != 0) {
      jedisConnectionFactory.setDatabase(0);
    }
    jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
    jedisConnectionFactory.afterPropertiesSet();
    return jedisConnectionFactory;
  }

  //5. Connect the factory
//  public RedisConnectionFactory redisConnectionFactory() {
//
//    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
//    redisStandaloneConfiguration.setHostName("localhost");
//    redisStandaloneConfiguration.setPort(6379);
//    redisStandaloneConfiguration.setDatabase(0);
//    JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jedisClientConfigurationBuilder = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
//    jedisClientConfigurationBuilder.poolConfig(this.jedisPoolConfig());
//    JedisClientConfiguration jedisClientConfiguration = jedisClientConfigurationBuilder.build();
//    return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
//  }
//
//  //6. Redis serialization
//  public StringRedisSerializer stringRedisSerializer() {
//    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//    return stringRedisSerializer;
//  }

  @Bean(name = "againRedisTemplate")
  public RedisTemplate<String,Object> aredisTemplate(){
//  public StringRedisTemplate stringRedisTemplate() {
    RedisTemplate<String,Object> stringRedisTemplate = new RedisTemplate<>();
    RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
    //1. Set the serializer of Jason
    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);
    //2. Set up factory
    stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory());
    //3. Set the serializer of the key
    stringRedisTemplate.setKeySerializer(stringRedisSerializer);
//    stringRedisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    //4. Set the serializer of Value (I set it to String type here)
    stringRedisTemplate.setValueSerializer(stringRedisSerializer);
    //5. Set Hash, which is of type Json
    stringRedisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//    StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
//    stringRedisTemplate.setConnectionFactory(this.redisConnectionFactory());
    return stringRedisTemplate;
  }
}

Keywords: Java Redis

Added by aeonsky on Tue, 21 Dec 2021 14:02:09 +0200