本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
目录
Spring Boot 整合 Redis 的哨兵模式
在开发中,Redis 是一个非常流行和强大的缓存数据库。为了保证高可用性和容错性,Redis 提供了哨兵模式(Sentinel)来处理主从切换和故障转移。 本篇技术博客将介绍如何在 Spring Boot 应用中使用 Redis 的哨兵模式进行高可用缓存服务的搭建。
准备工作
在开始之前,确保你已经安装和启动了 Redis 服务器,并按照 Redis 的哨兵模式配置了主节点和从节点。
添加依赖
在 pom.xml 文件中添加 Spring Data Redis 和 Jedis 的依赖:
xmlCopy code
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
Redis 配置
在 application.yaml 文件中进行 Redis 的配置,包括主服务器和哨兵节点的信息:
yamlCopy code
spring:
redis:
sentinel:
master: mymaster # 主节点名称
nodes: host1:port1,host2:port2,host3:port3 # 哨兵节点列表
创建 Redis 配置类
创建一个 Redis 的配置类,用于配置 Redis 连接工厂和缓存管理器:
javaCopy code
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.sentinel.master}")
private String master;
@Value("${spring.redis.sentinel.nodes}")
private String sentinelNodes;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration()
.master(master);
Set<String> nodes = new HashSet<>(Arrays.asList(sentinelNodes.split(",")));
nodes.forEach(node -> {
String[] parts = node.split(":");
sentinelConfiguration.sentinel(parts[0], Integer.parseInt(parts[1]));
});
return new JedisConnectionFactory(sentinelConfiguration);
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)); // 设置缓存过期时间为10分钟
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.transactionAware()
.build();
}
}
在这个配置类中,我们首先通过读取配置文件中的主节点名称和哨兵节点列表来创建 RedisSentinelConfiguration 对象。然后,我们遍历哨兵节点列表并将它们添加到配置中。 接下来,我们使用 JedisConnectionFactory 来创建 RedisConnectionFactory,并将之前创建的 RedisSentinelConfiguration 传递给它。 最后,我们创建了 RedisCacheConfiguration 并设置了一个常见的缓存过期时间,然后使用它来构建 RedisCacheManager。
使用 Redis 缓存
在 Spring Boot 的服务类或控制器中,我们可以使用 @Cacheable、@CachePut 和 @CacheEvict 等注解来实现缓存功能。这些注解可以应用于方法上,以指定需要缓存的方法或操作。
javaCopy code
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
@CachePut(value = "users", key = "#user.id")
public User saveUser(User user) {
return userRepository.save(user);
}
@CacheEvict(value = "users", key = "#id")
public void deleteUserById(Long id) {
userRepository.deleteById(id);
}
}
运行应用程序
现在,我们已经完成了 Spring Boot 的 Redis 哨兵模式配置和使用 Redis 缓存的代码编写。 运行应用程序,并在需要使用缓存的地方使用上述的 @Cacheable、@CachePut 和 @CacheEvict 注解,Spring Boot 将自动处理缓存,并通过 Redis 的哨兵模式提供高可用性和容错性。
当结合实际应用场景进行 Redis 的哨兵模式配置时,通常是为了实现高可用的缓存服务。下面给出一个示例代码,假设我们有一个商品管理系统,我们使用 Redis 缓存来存储商品信息,并保证缓存的高可用性。 首先,我们需要在 Spring Boot 应用中配置 Redis 的哨兵模式并使用 Redis 缓存。可以参考上面提到的配置和代码。 然后,我们可以在商品服务类中使用 Redis 缓存来存储和获取商品信息。
javaCopy code
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Cacheable(value = "products", key = "#id")
public Product getProductById(Long id) {
// 先从缓存中获取商品信息
// 如果缓存中不存在,从数据库中获取,并将结果存入缓存
return productRepository.findById(id).orElse(null);
}
@CachePut(value = "products", key = "#product.id")
public Product saveProduct(Product product) {
// 保存商品信息到数据库,并将结果存入缓存
return productRepository.save(product);
}
@CacheEvict(value = "products", key = "#id")
public void deleteProductById(Long id) {
// 从数据库中删除商品信息,并从缓存中移除对应的数据
productRepository.deleteById(id);
}
}
在上述代码中,我们使用 @Cacheable 注解将 getProductById 方法标记为可缓存的。当调用该方法时,Spring Boot 会首先尝试从缓存中获取商品信息。如果缓存中存在对应的数据,则直接返回缓存中的数据;如果缓存中不存在,则会从数据库中获取商品信息,并将结果存入缓存。 使用 @CachePut 注解将 saveProduct 方法标记为缓存更新的操作。该方法用于保存或更新商品信息到数据库,并将最新的商品信息存入缓存。通过指定相同的缓存名称和缓存键,可以覆盖之前的缓存数据。 使用 @CacheEvict 注解将 deleteProductById 方法标记为缓存失效的操作。该方法用于删除数据库中的商品信息,并从缓存中移除相应的数据。 通过以上示例代码,我们可以实现基于 Redis 的哨兵模式的高可用缓存服务。在生产环境中,可以部署多个 Redis 节点,并使用哨兵模式来实现主从切换和故障转移,以确保缓存服务的可用性和容错性。 请注意,上述示例代码中的 ProductRepository 是一个假设的商品数据访问接口,具体的实现根据实际情况进行编写。另外,还需要在 application.yaml 中配置正确的 Redis 主节点和哨兵节点的信息。
Spring Boot 中如何使用 Redis 的哨兵模式: 首先,确保已经引入 Spring Data Redis 和 Lettuce 依赖。
xmlCopy code
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
接下来,在 application.properties(或 application.yml)中进行配置,包括 Redis 的哨兵节点和密码等信息:
propertiesCopy code
# Redis配置
spring.redis.sentinel.master=my-master
spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
spring.redis.password=your-password
然后,使用 @Configuration 注解创建一个配置类,配置 RedisTemplate 和 LettuceConnectionFactory:
javaCopy code
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration() {
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
configuration.master("my-master");
configuration.sentinel("127.0.0.1", 26379);
configuration.sentinel("127.0.0.1", 26380);
configuration.sentinel("127.0.0.1", 26381);
configuration.setPassword(RedisPassword.of("your-password"));
return configuration;
}
@Bean
public LettuceConnectionFactory lettuceConnectionFactory(RedisSentinelConfiguration redisSentinelConfiguration) {
return new LettuceConnectionFactory(redisSentinelConfiguration);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
return redisTemplate;
}
}
最后,可以在业务逻辑中使用自动注入的 RedisTemplate 来操作 Redis 数据:
javaCopy code
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void setValue(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
}
在上述示例代码中,我们首先创建了一个 RedisConfig 配置类,通过 @Bean 注解配置了 RedisSentinelConfiguration 和 LettuceConnectionFactory。然后,我们创建了一个 RedisTemplate 并将 LettuceConnectionFactory 注入其中。最后,我们在 RedisService 服务类中使用自动注入的 RedisTemplate 来操作 Redis 数据。 请注意,上述示例代码中的配置信息和 Redis 连接参数是示例,实际应用中需要根据实际情况进行配置和更改。
总结
通过本篇技术博客,我们学习了如何在 Spring Boot 应用中使用 Redis 的哨兵模式进行高可用性缓存服务的搭建。 要注意的是,为了实现真正的高可用性,需要在实际生产环境中正确配置 Redis 的主节点和哨兵节点。