一、简介

使用RedisConfig配置类的方式进行Redis standalone(单节点)、cluster(主从集群)、sentinel(哨兵集群)的灵活配置。

二、代码

2.1 依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.6.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <!-- 常用文件IO转换 MultipartFile  -> File   -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <!-- 常用工具 StringUtils   -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

2.2 YML配置文件

在这里插入图片描述
application.yml

spring:
  profiles:
    active: standalone
#    active: cluster
#    active: sentinel

application-cluster.yml

server:
  port: 8080
  servlet:
    context-path: /testRedis
spring:
  application:
    name: TestRedis
  redis:
    database: 0
    lettuce:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0
    # Redis Cluster 集群配置
    cluster:
      nodes:
        - 192.168.184.58:7000
        - 192.168.184.58:7001
        - 192.168.184.58:7002
        - 192.168.184.59:7000
        - 192.168.184.59:7001
        - 192.168.184.59:7002
      max-redirects: 3
    password: 
    timeout: 5000
# Redis连接池配置
jedis:
  pool:
    config:
      maxTotal: 100
      maxWaitMillis: 5000
      maxIdle: 10

application-sentinel.yml

server:
  port: 8080
  servlet:
    context-path: /testRedis
spring:
  application:
    name: TestRedis
  redis:
    sentinel:
      master:
      nodes:
    password:

application-standalone.yml

server:
  port: 8080
  servlet:
    context-path: /testRedis
spring:
  application:
    name: TestRedis
  redis:
    host: localhost
    lettuce:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0
    port: 7000
    password: 123456
# Redis连接池配置
jedis:
  pool:
    config:
      maxTotal: 200
      maxWaitMillis: 5000
      maxIdle: 100



2.3 RedisConfig

package com.haobai.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.*;
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.StringRedisSerializer;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * @author :LiuShihao
 * @date :Created in 2021/11/22 3:52 下午
 * @desc :Redis配置类
 * org.springframework.boot.autoconfigure.data.redis.RedisProperties 会根据配置自动加载为一个bean
 */
@Slf4j
@Configuration
public class RedisConfig {

    /**
     * @param properties  org.springframework.boot.autoconfigure.data.redis.RedisProperties
     *
     * 如果使用的是直接连接redis的方式,即每次连接都创建新的连接。当并发量剧增时,这会带来性能上开销,同时由于没有对连接数进行限制,则可能使服务器崩溃导致无法响应。
     * 所以我们一般都会建立连接池,事先初始化一组连接,供需要redis连接的线程取用。
     *
     * 使用RedisStandaloneConfiguration、RedisSentinelConfiguration、RedisClusterConfiguration三种方式配置连接信息。
     *
     * @return
     */
    @Bean(name = "RedisConnectionFactory")
    public RedisConnectionFactory connectionFactory(RedisProperties properties){
        //Jedis连接工厂 JedisConnectionFactory是RedisConnectionFactory子类
        JedisConnectionFactory factory;
        //RedisSentinelConfiguration 是 RedisConfiguration 的子类
        RedisSentinelConfiguration sentinelConfig = getSentinelConfiguration(properties);
        RedisClusterConfiguration clusterConfiguration = getClusterConfiguration(properties);
        if (sentinelConfig != null) {
            log.info("Redis Sentinel 集群配置...");
            factory = new JedisConnectionFactory(sentinelConfig);
        } else if (clusterConfiguration != null) {
            log.info("Redis Cluster 集群配置...");
            factory = new JedisConnectionFactory(clusterConfiguration);
        } else {
            log.info("Redis Standalone单节点配置...");
            RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
            redisStandaloneConfiguration.setHostName(properties.getHost());
            redisStandaloneConfiguration.setPort(properties.getPort());
            redisStandaloneConfiguration.setPassword(properties.getPassword());
            factory = new JedisConnectionFactory(redisStandaloneConfiguration);
        }

        return factory;
    }

    /**
     * 主从集群信息配置
     * @param properties
     * @return
     */
    private RedisClusterConfiguration getClusterConfiguration(RedisProperties properties) {
        RedisProperties.Cluster cluster = properties.getCluster();

        if (cluster != null) {
            RedisClusterConfiguration config = new RedisClusterConfiguration(cluster.getNodes());
            if (properties.getPassword() != null){
                config.setPassword(properties.getPassword());
            }
            if (cluster.getMaxRedirects() != null) {
                config.setMaxRedirects(cluster.getMaxRedirects());
            }
            return config;
        }
        return null;
    }

    /**
     * 哨兵集群信息配置
     * @param properties
     * @return
     */
    private RedisSentinelConfiguration getSentinelConfiguration(RedisProperties properties) {
        RedisProperties.Sentinel sentinel = properties.getSentinel();
        if (sentinel != null) {
            RedisSentinelConfiguration config = new RedisSentinelConfiguration();
            config.master(sentinel.getMaster());
            config.setSentinels(createSentinels(sentinel));
            if (properties.getPassword() != null){
                config.setPassword(properties.getPassword());
            }
            return config;
        }
        return null;
    }

    /**
     * 创建哨兵集群节点
     * @param sentinel
     * @return
     */
    private static List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) {
        List<RedisNode> nodes = new ArrayList<>();
//        for (String node : StringUtils.commaDelimitedListToStringArray(sentinel.getNodes())) {
        for (String node : sentinel.getNodes()) {
            String[] parts = StringUtils.split(node, ":");
            Assert.state(parts.length == 2, "redis哨兵地址配置不合法!");
            nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
        }
        return nodes;
    }

    @Bean(name = "RedisTemplate")
    public RedisTemplate redisTemplate(@Qualifier("RedisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {


        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);


        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());

        return template;
    }
    @Bean(name = "StringRedisTemplate")
    public StringRedisTemplate StringRedisTemplate(@Qualifier("RedisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {

        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(redisConnectionFactory);

        return stringRedisTemplate;
    }

    /**
     *
     * 使用
     * 连接池配置
     * @param maxTotal
     * @param maxWaitMillis
     * @param maxIdle
     * @return
     */
    @Bean(name = "JedisPoolConfig")
    public JedisPoolConfig jedisPoolConfig(@Value("${jedis.pool.config.maxTotal:100}") int maxTotal,
                                           @Value("${jedis.pool.config.maxWaitMillis:5000}") int maxWaitMillis,
                                           @Value("${jedis.pool.config.maxIdle:10}") int maxIdle) {
        log.info("Redis连接池配置...");
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMaxWaitMillis(maxWaitMillis);
        return config;
    }

}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐