开发者

springboot之如何同时连接多个redis

开发者 https://www.devze.com 2023-04-15 10:41 出处:网络 作者: 窦再兴
目录技术选型 Springboot连接reids的三个客户端代码部分maven pom引用application.yml配置Configuration代码启动失败日志启动成功日志类中使用总结线上服务需要连接三个Redis服务器;业务背景不能介绍,直接上代
目录
  • 技术选型 
    • Springboot连接reids的三个客户端
  • 代码部分
    • maven pom引用
    • application.yml配置
    • Configuration代码
    • 启动失败日志
    • 启动成功日志
  • 类中使用
    • 总结

      线上服务需要连接三个Redis服务器;业务背景不能介绍,直接上代码:

      技术选型 

      Springboot连接reids的三个客户端

      Jedis:是Redis的Java实现客户端,提供了比较全面的Redis命令的支持,编程复杂的redis操作需要使用它;springboot1.x 默认集成;据说在高并发下有并发性问题出现;

      Lettuce:高级Redis客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器,springboot 2.x 默认集成

      Redission:Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, blockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。暂时企业级开发感觉只是使用了分布式锁

      结论:

      单个redis随便使用哪个客户端都可以,也可以使用 Jedis + Redission 或者 Lettuce + Redission;

      由于Jedis使用和研究比较多,此处使用Jedis抛砖引玉,实现三组redis + 分布式锁;Lettuce版本也可以根据此思路编写;

      代码部分

      maven pom引用

              <dependency>
      			<groupId>org.springframework.boot</groupId>
      			<artifactId>spring-boot-starter-data-redis</artifactId>
      			<exclusions>
      				<!-- 不依赖Redis的异步客户端lettuce -->
      				<exclusion>
      					<groupId>io.lettuce</groupId>
      					<artifactId>lettuce-core</artifactId>
      				</exclusion>
      			</exclusions>
      		</dependency>
       
      		<dependency>
      			<groupId>redis.clients</groupId>
      			<artifactId>jedis</artifactId>
      		</dependency>

      application.yml配置

      spring:
        redis:
          r1:
            host: 192.168.1.210
            port: 6379
            password: 
            #cluster:
              #nodes: 192.168.1.101:6379,192.168.1.102:6379,192.1编程客栈68.1.103:6379
          r2:
            host: 192.168.1.211
            port: 6379
            password: 
            #cluster:
              #nodes: 192.168.1.104:6379,192.168.1.105:6379,192.168.1.106:6379
          r3:
            host: 192.168.1.212
            port: 6379
            password: 
            #cluster:
              #nodes: 192.168.1.107:6379,192.168.1.108:6379,192.168.1.109:6379

      Configuration代码

       
      import java.util.HashSet;
      import java.util.Set;
       
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.data.redis.connection.RedisClusterConfiguration;
      import org.springframework.data.redis.connection.RedisConnection;
      import org.springframework.data.redis.connection.RedisConnectionFactory;
      import org.springframework.data.redis.connection.RedisNode;
      import org.springframework.data.redis.connection.RedisPassword;
      import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
      import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
      import org.springframework.data.redis.core.RedisTemplate;
       
      import cn.hutool.core.util.StrUtil;
      import lombok.extern.slf4j.Slf4j;
      import redis.clients.jedis.JedisPoolConfig;
       
      /**
       * redis配置 三个redis同时存在
       * @author douzi
       * @date  2021-12-2 09:00:00
       */
      @Slf4j
      @Configuration
      public class RedisJedisConfig2 {
      	// r1 redis 配置信息
          @Value("${spring.redis.r1.host:}")
          private String r1Host;
       
          @Value("${spring.redis.r1.port:}")
          private Integer r1Port;
       
          @Value("${spring.redis.r1.password:}")
          private String r1Password;
          
          @Value("${spring.redis.r1.cluster.nodes:}")
          private String r1Nodes;
       
          //r2 redis 配置信息
          @Value("${spring.redis.r2.host:}")
          private String r2Host;
       
          @Value("${spring.redis.r2.port:}")
          private Integer r2Port;
       
          @Value("${spring.redis.r2.password:}")
          private String r2Password;
          
          @Value("${spring.redis.r2.cluster.nodes:}")
          private String r2Nodes;
          
          //r3 redis 配置信息
          @Value("${spring.redis.r3.host:}")
          private String r3Host;
       
          @Value("${spring.redis.r3.port:}")
          private Integer r3Port;
       
          @Value("${spring.redis.r3.password:}")
          private String r3Password;
          
          @Value("${spring.redis.r3.cluster.nodes:}")
          private String r3Nodes;
       
          /**
           * connectionFactory 配置工厂
           */
          public RedisConnectionFactory connectionFactory(
          		RedisStandaloneConfiguration redisStandaloneConfiguration, 
          		RedisClusterConfiguration redisClusterConfiguration, 
          		JedisPoolConfig jedisPoolConfig) {
          	if (redisStandaloneConfiguration == null && redisClusterConfiguration == null) {
          		log.error("==============请添加redis配置================");
          		return null;
          	}
          	
              JedisConnectionFactory jedisConnectionFactory = null;
              
              if (redisStandaloneConfiguration != null) {
              	jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
              } else {
              	jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
              }
              jedisConnectionFactory.afterPropertiesSet();
              
              // 检查是否可用
              RedisConnection connection = null;
              try {
              	connection = jedisConnectionFactory.getConnection();
              	log.info("reids是否可用:" + !connection.isClosed());
              } catch(Exception e) {
              	log.error("reids不可用,请检查组件是否启动:",e);
              } finally {
              	connection.close();
              }
              
              return jedisConnectionFactory;
          }
       
          /**
           * poolConfig连接池配置 只有集群时使用 直接写死,不让外部配置了
           * @return
           */
          public JedisPoolConfig poolConfig() {
          	JedisPoolConfig config = new JedisPoolConfig();
              config.setMaxTotal(200);
              config.setMaxIdle(50);
              config.setMinIdle(8);
              config.setMaxWaitMillis(10000);         // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
              config.setTestOnBorrow(true);           // 在获取连接的时候检查有效性, 默认false
              config.setTestOnReturn(false);          // 调用returnObject方法时,是否进行有效检查
              config.setTestWhileIdle(true);          // Idle时进行连接扫描
              config.setTimeBetweenEvictionRunsMillis(30000);     // 表示idle object evitor两次扫描之间要sleep的毫秒数
              config.setNumTestsPerEvictionRun(10);               // 表示idle object evitor每次扫描的最多的对象数
              config.setMinEvictableIdleTimeMillis(60000);        // 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
              return config;
          }
          
          /**
           * redisStandaloneConfiguration 单机版配置
           * @param host
           * @param port
           * @param password
           * @param index
           * @return
           */
          public RedisStandaloneConfiguration redisStandaloneConfiguration(String host, int port, String password, int index) {
          	RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
          	
          	if (StrUtil.isNotBlank(开发者_Js入门password)) {
          		redisStandaloneConfiguration.setPassword(password);
              }
          	if (index != 0) {
          		redisStandaloneConfiguration.setDatabase(index);
              }
          	return redisStandaloneConfiguration;
          }
          
          /**
           * redisClusterConfiguration 集群配置
           * @param clusterNodes
           * @param password
           * @return
           */
          public RedisClusterConfiguration redisClusterConfiguration(String clusterNodes, String password) {
              RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
              // Set<RedisNode> clusterNodes
              String[] serverArray = clusterNodes.split(",");
              Set<RedisNode> nodes = new HashSet<RedisNode>();
              for (String ipPort : serverArray) {
                  String[] ipAndPort = ipPort.split(":");
                  nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));
              }
              redisClusterConfiguration.setClusterNodes(nodes);
              redisClusterConfiguration.setMaxRedirects(6);
              i编程客栈f (StrUtil.isNotBlank(password)) {
              	redisClusterConfiguration.setPassword(RedisPassword.of(password));
              }
              return redisClusterConfiguration;
          }
       
          @Bean(name = "redisR1Template")
          public RedisTemplate<String, Object> redisR1Template() {
          	RedisTemplate<String, Object> template = new RedisTemplate<>();
              RedisStandaloneConfiguration redisStandaloneConfiguration = null;
              RedisClusterConfiguration redisClusterConfiguration = null;
              if (StrUtil.isNotBlank(r1Host) && StrUtil.isBlank(r1Nodes)) {
              	redisStandaloneConfiguration = redisStandaloneConfiguration(r1Host, r1Port, r1Password, 0);
              } else if (StrUtil.isNotBlank(r1Nodes)) {
              	redisClusterConfiguration = redisClusterConfiguration(r1Nodes, r1Password);
              }
              log.info("=========================R1 redis信息 开始===============================");
              template.setConnectionFactory(connectionFactory(redisStandaloneConfiguration, redisClusterConfiguration, poolConfig()));
              log.info("=========================R1 redis信息 结束===============================");
              return template;
          }
       
          @Bean(name = "redisR2Template")
          public RedisTemplate<String, Object> redisR2Template() {
          	RedisTemplate<String, Object> template = new RedisTemplate<>();
              RedisStandaloneConfiguration redisStandaloneConfiguration = null;
              RedijssClusterConfiguration redisClusterConfiguration = null;
              if (StrUtil.isNotBlank(r2Host) && StrUtil.isBlank(r2Nodes)) {
              	redisStandaloneConfiguration = redisStandaloneConfiguration(r2Host, r2Port, r2Password, 0);
              } else if (StrUtil.isNotBlank(r2Nodes)) {
              	redisClusterConfiguration = redisClusterConfiguration(r2Nodes, r2Password);
              }
              log.info("=========================R2 redis信息 开始===============================");
              template.setConnectionFactory(connectionFactory(redisStandaloneConfiguration, redisClusterConfiguration, poolConfig()));
              log.info("=========================R2 redis信息 结束===============================");
              return template;
          }
          
          @Bean(name = "redisR3Template")
          public RedisTemplate<String, Object> redisR3Template() {
          	RedisTemplate<String, Object> template = new RedisTemplate<>();
              RedisStandaloneConfiguration redisStandaloneConfiguration = null;
              RedisClusterConfiguration redisClusterConfiguration = null;
              if (StrUtil.isNotBlank(r3Host) && StrUtil.isBlank(r3Nodes)) {
              	redisStandaloneC编程客栈onfiguration = redisStandaloneConfiguration(r3Host, r3Port, r3Password, 0);
              } else if (StrUtil.isNotBlank(r3Nodes)) {
              	redisClusterConfiguration = redisClusterConfiguration(r3Nodes, r3Password);
              }
              log.info("=========================R3 redis信息 开始===============================");
              template.setConnectionFactory(connectionFactory(redisStandaloneConfiguration, redisClusterConfiguration, poolConfig()));
              log.info("=========================R3 redis信息 结束===============================");
              return template;
          }
      }

      其中在connectionFactory方法中,添加了,自动检查redis是否连接成功的代码,在启动项目时即可判断是否连接成功。

      启动失败日志

      springboot之如何同时连接多个redis

      启动成功日志

      springboot之如何同时连接多个redis

      类中使用

      @RestController
      @RequestMapping("/redis")
      public class TestRedisController {
      	@Autowired
      	RedisTemplate<String, Object> redisR1Template;
      	@Autowired
      	RedisTemplate<String, Object> redisR2Template;
      	@Autowired
      	RedisTemplate<String, Object> redisR3Template;
      	
      	@GetMapping("/cs")
      	public String test() {
      		redisR1Template.opsForValue().get("1");
      		redisR2Template.opsForValue().get("1");
      		redisR3Template.opsForValue().get("1");
      		return "1";
      	}
      }

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号