Loading... # Redisson连接Redis单机&集群&哨兵配置示例 ## Redisson简介 1. **定义与用途**:Redisson是一个用于Redis的Java客户端。它提供了许多分布式服务,包括但不限于可锁定的Map、Set、List等数据结构。它的设计目标是让使用Redis更加方便,并且提供了许多高级特性,比如分布式锁、分布式集合等。 2. **分布式锁**:Redisson通过提供可靠的分布式锁机制,确保在高并发场景下资源的一致性和安全性。这使得多个JVM实例可以安全地共享和更新同一份数据。 3. **支持的Redis数据结构**:Redisson实现了多种基于Redis的数据结构,如分布式Map、Set、List等。它将这些数据结构以一种易于理解和使用的Java对象形式呈现给开发者。 4. **事件监听器**:Redisson支持事件监听机制,允许用户注册监听器来处理特定的数据变化或网络连接状态的变化。 5. **集群模式**:除了支持单机模式外,Redisson还支持Redis集群模式,能够在多个Redis节点之间进行故障转移和负载均衡。 6. **异步API**:Redisson提供了丰富的异步API,允许开发者以非阻塞的方式执行操作,从而提高应用程序的响应速度和吞吐量。 7. **Spring集成**:Redisson与Spring框架有很好的集成性,可以通过简单的配置就可以将其集成到Spring项目中,简化了使用过程。 8. **性能优化**:Redisson对某些操作进行了优化,以减少网络延迟和提升整体性能。例如,它能够批量执行命令以减少往返次数。 9. **社区和支持**:作为一个开源项目,Redisson拥有活跃的社区和持续的支持。这对于长期稳定性和功能扩展是非常重要的。 ## Redisson配置 在查阅了多位博主关于 Redisson 的配置后,我们发现大多数示例仅限于单机模式的配置。然而,在实际生产环境中,Redis 的部署方式通常更为复杂,包括主从模式、哨兵模式以及集群模式等。由于不同模式下 Redis 的工作方式有所不同,因此 Redisson 在这些模式下的配置也会有所差异。此外,鉴于目前大多数项目都采用了 Spring Boot 架构,Redis 的使用也大多遵循 Spring 官方推荐的 starter 方式进行集成。 基于上述背景,本文将聚焦于如何在 Spring Boot 1.5.22.RELEASE 版本的项目中,结合 spring-boot-starter-data-redis,实现 Redisson 的高效集成与应用。 ## pom依赖 ```XML <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.22.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.idto</groupId> <artifactId>redis-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>redis-demo</name> <description>redis-demo</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.15.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> <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> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ``` ## RedissonClient创建 针对Redis不同的部署模式,对RedissonClient进行不同的初始化 ```java package com.idto.config; import org.apache.commons.lang3.StringUtils; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.redisson.config.SentinelServersConfig; import org.redisson.config.SingleServerConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; import java.util.Objects; @Configuration public class RedissonConfig { Logger log = LoggerFactory.getLogger(RedissonConfig.class); # 直接使用starter注入的redis配置信息 @Autowired private RedisProperties redisProperties; private int timeout = 3000; private int connectionPoolSize = 64; private int connectionMinimumIdleSize = 10; private int pingConnectionInterval = 60000; private static String ADDRESS_PREFIX = "redis://"; /** * 单机模式 */ @Bean public RedissonClient initBean() { // 哨兵模式 RedisProperties.Sentinel sentinel = redisProperties.getSentinel(); if (Objects.nonNull(sentinel)) { log.info("redis is sentinel mode"); return redissonSentinel(); } // 集群模式 RedisProperties.Cluster cluster = redisProperties.getCluster(); if (Objects.nonNull(cluster)) { log.info("redis is cluster mode"); return redissonCluster(); } // 单机模式 String host = redisProperties.getHost(); if (StringUtils.isNotBlank(host)) { log.info("redis is single mode"); return redissonSingle(); } log.error("redisson config can not support this redis mode"); return null; } /** * 单机模式 */ private RedissonClient redissonSingle() { String host = redisProperties.getHost(); String password = redisProperties.getPassword(); int port = redisProperties.getPort(); // 设置超时时间 if (redisProperties.getTimeout() > 0) { timeout = redisProperties.getTimeout(); } // 声明一个配置类 Config config = new Config(); SingleServerConfig serverConfig = config.useSingleServer() .setAddress(ADDRESS_PREFIX + host + ":" + port) .setTimeout(timeout) .setPingConnectionInterval(pingConnectionInterval) .setConnectionPoolSize(this.connectionPoolSize) .setConnectionMinimumIdleSize(this.connectionMinimumIdleSize); // 判断密码 if (!StringUtils.isEmpty(password)) { serverConfig.setPassword(password); } return Redisson.create(config); } /** * 哨兵模式 */ private RedissonClient redissonSentinel() { // mymaster String masterName = redisProperties.getSentinel().getMaster(); // 127.0.0.1:26389,127.0.0.1:26379 String nodes = redisProperties.getSentinel().getNodes(); String password = redisProperties.getPassword(); // 设置超时时间 if (redisProperties.getTimeout() > 0) { timeout = redisProperties.getTimeout(); } // 声明一个配置类 Config config = new Config(); SentinelServersConfig sentinelServersConfig = config.useSentinelServers(); // 扫描间隔 sentinelServersConfig.setScanInterval(2000); // 判断密码 if (!StringUtils.isEmpty(password)) { sentinelServersConfig.setPassword(password); } sentinelServersConfig.setMasterName(masterName); String[] nodeArr = StringUtils.split(nodes, ","); for (int i = 0; i < nodeArr.length; i++) { nodeArr[i] = ADDRESS_PREFIX + nodeArr[i]; } // 添加redis节点 sentinelServersConfig.addSentinelAddress(nodeArr); return Redisson.create(config); } /** * 集群模式 */ private RedissonClient redissonCluster() { // 192.168.116.156:1901,192.168.116.156:1902 List < String > nodes = redisProperties.getCluster().getNodes(); String password = redisProperties.getPassword(); // 设置超时时间 if (redisProperties.getTimeout() > 0) { timeout = redisProperties.getTimeout(); } // 声明一个配置类 Config config = new Config(); ClusterServersConfig clusterServersConfig = config.useClusterServers(); // 扫描间隔 clusterServersConfig.setScanInterval(2000); // 判断密码 if (!StringUtils.isEmpty(password)) { clusterServersConfig.setPassword(password); } // 添加redis节点 for (String node: nodes) { clusterServersConfig.addNodeAddress(ADDRESS_PREFIX + node); } return Redisson.create(config); } } ``` ## Redis配置 ```java spring: redis: # 单机/主从模式 # host: 192.168.8.129 # port: 7001 # 哨兵模式 # sentinel: # master: mymaster # nodes: 192.168.8.129:27001,192.168.8.129:27002,192.168.8.129:27003 # 集群模式 cluster: nodes: 192.168.8.129:8001,192.168.8.129:8002,192.168.8.129:8003,192.168.8.129:8004,192.168.8.129:8005,192.168.8.129:8006 # redis服务数据库下标 database: 2 # redis服务密码 # password: 111111 pool: max-idle: 100 min-idle: 1 max-active: 10 max-wait: 5000 ``` ## Redisson简单测试 ```java package com.idto.controller; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.TimeUnit; @RestController public class RedissionController { Logger log = LoggerFactory.getLogger(RedissionController.class); @Autowired private RedissonClient redissonClient; @GetMapping("/lock") public String lock() throws InterruptedException { String lockKey = "lock"; RLock lock = redissonClient.getLock(lockKey); boolean lockResult = lock.tryLock(); log.info("lock key {} lock result {}", lockKey, lockResult); TimeUnit.SECONDS.sleep(5); lock.unlock(); log.info("lock key {} unlock ", lockKey); return System.currentTimeMillis() + "---" + lockResult; } } ``` 最后修改:2024 年 12 月 05 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏