Spring Boot 与 Redis 集成最佳实践

发布时间:2026/7/31 7:44:00

Spring Boot 与 Redis 集成最佳实践 Spring Boot 与 Redis 集成最佳实践前言核心概念1. Redis 基本概念键值存储Redis 是一个键值对数据库数据结构支持字符串、列表、集合、有序集合、哈希等数据结构内存存储数据存储在内存中速度快持久化支持 RDB 和 AOF 持久化高可用支持主从复制和哨兵模式集群支持 Redis Cluster 集群2. Spring Data Redis 核心组件RedisTemplate用于操作 RedisStringRedisTemplate专门用于操作字符串类型RedisConnectionFactory创建 Redis 连接RedisSerializer序列化和反序列化 Redis 数据RedisCacheManager管理 Redis 缓存集成配置1. 依赖配置添加 Spring Data Redis 依赖dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency /dependencies2. 配置文件配置 Redis 连接信息spring: redis: host: localhost port: 6379 password: database: 0 timeout: 10000 lettuce: pool: max-active: 8 max-wait: -1 max-idle: 8 min-idle: 03. Redis 配置类配置 RedisTemplateConfiguration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // 设置键序列化器 template.setKeySerializer(new StringRedisSerializer()); // 设置值序列化器 template.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class)); // 设置哈希键序列化器 template.setHashKeySerializer(new StringRedisSerializer()); // 设置哈希值序列化器 template.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class)); template.afterPropertiesSet(); return template; } Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } }基本操作1. 字符串操作Service public class RedisService { private final RedisTemplateString, Object redisTemplate; private final StringRedisTemplate stringRedisTemplate; public RedisService(RedisTemplateString, Object redisTemplate, StringRedisTemplate stringRedisTemplate) { this.redisTemplate redisTemplate; this.stringRedisTemplate stringRedisTemplate; } // 字符串操作 public void setString(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } public String getString(String key) { return stringRedisTemplate.opsForValue().get(key); } public void setStringWithExpiration(String key, String value, long timeout, TimeUnit unit) { stringRedisTemplate.opsForValue().set(key, value, timeout, unit); } public Boolean deleteString(String key) { return stringRedisTemplate.delete(key); } }2. 哈希操作Service public class RedisService { private final RedisTemplateString, Object redisTemplate; public RedisService(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } // 哈希操作 public void putHash(String key, String hashKey, Object value) { redisTemplate.opsForHash().put(key, hashKey, value); } public Object getHash(String key, String hashKey) { return redisTemplate.opsForHash().get(key, hashKey); } public MapObject, Object getHashAll(String key) { return redisTemplate.opsForHash().entries(key); } public Boolean deleteHash(String key, Object... hashKeys) { return redisTemplate.opsForHash().delete(key, hashKeys) 0; } }3. 列表操作Service public class RedisService { private final RedisTemplateString, Object redisTemplate; public RedisService(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } // 列表操作 public void leftPush(String key, Object value) { redisTemplate.opsForList().leftPush(key, value); } public void rightPush(String key, Object value) { redisTemplate.opsForList().rightPush(key, value); } public Object leftPop(String key) { return redisTemplate.opsForList().leftPop(key); } public Object rightPop(String key) { return redisTemplate.opsForList().rightPop(key); } public ListObject range(String key, long start, long end) { return redisTemplate.opsForList().range(key, start, end); } }4. 集合操作Service public class RedisService { private final RedisTemplateString, Object redisTemplate; public RedisService(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } // 集合操作 public void addSet(String key, Object... values) { redisTemplate.opsForSet().add(key, values); } public SetObject getSet(String key) { return redisTemplate.opsForSet().members(key); } public Boolean isMember(String key, Object value) { return redisTemplate.opsForSet().isMember(key, value); } public Long removeSet(String key, Object... values) { return redisTemplate.opsForSet().remove(key, values); } }5. 有序集合操作Service public class RedisService { private final RedisTemplateString, Object redisTemplate; public RedisService(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } // 有序集合操作 public void addZSet(String key, Object value, double score) { redisTemplate.opsForZSet().add(key, value, score); } public SetObject rangeZSet(String key, long start, long end) { return redisTemplate.opsForZSet().range(key, start, end); } public SetObject rangeByScoreZSet(String key, double min, double max) { return redisTemplate.opsForZSet().rangeByScore(key, min, max); } public Long removeZSet(String key, Object... values) { return redisTemplate.opsForZSet().remove(key, values); } }高级特性1. 缓存使用 Redis 作为缓存Configuration EnableCaching public class CacheConfig { Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration config RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(10)) .prefixCacheNameWith(myapp:) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer(Object.class))); return RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(config) .build(); } } Service public class UserService { Autowired private UserRepository userRepository; Cacheable(value users, key #id) public User findById(Long id) { return userRepository.findById(id).orElse(null); } CachePut(value users, key #user.id) public User save(User user) { return userRepository.save(user); } CacheEvict(value users, key #id) public void deleteById(Long id) { userRepository.deleteById(id); } }2. 会话管理使用 Redis 作为会话存储dependencies dependency groupIdorg.springframework.session/groupId artifactIdspring-session-data-redis/artifactId /dependency /dependenciesspring: session: store-type: redis redis: namespace: spring:session3. 分布式锁实现分布式锁Service public class RedisLockService { private final RedisTemplateString, Object redisTemplate; public RedisLockService(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } public boolean tryLock(String key, String value, long timeout, TimeUnit unit) { return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); } public void unlock(String key, String value) { String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; RedisScriptLong redisScript RedisScript.of(script, Long.class); redisTemplate.execute(redisScript, Collections.singletonList(key), value); } } Service public class OrderService { Autowired private RedisLockService redisLockService; public void processOrder(Long orderId) { String lockKey order:lock: orderId; String lockValue UUID.randomUUID().toString(); try { if (redisLockService.tryLock(lockKey, lockValue, 5, TimeUnit.SECONDS)) { // 处理订单 System.out.println(Processing order: orderId); Thread.sleep(2000); // 模拟处理时间 } else { System.out.println(Order is being processed by another thread); } } catch (Exception e) { e.printStackTrace(); } finally { redisLockService.unlock(lockKey, lockValue); } } }4. 消息队列使用 Redis 作为消息队列Service public class RedisMessageQueue { private final RedisTemplateString, Object redisTemplate; public RedisMessageQueue(RedisTemplateString, Object redisTemplate) { this.redisTemplate redisTemplate; } public void sendMessage(String queue, Object message) { redisTemplate.opsForList().rightPush(queue, message); } public Object receiveMessage(String queue) { return redisTemplate.opsForList().leftPop(queue); } public Object receiveMessage(String queue, long timeout, TimeUnit unit) { return redisTemplate.opsForList().leftPop(queue, timeout, unit); } } Service public class MessageProducer { Autowired private RedisMessageQueue messageQueue; public void sendOrderMessage(Order order) { messageQueue.sendMessage(order:queue, order); } } Service public class MessageConsumer { Autowired private RedisMessageQueue messageQueue; Scheduled(fixedRate 1000) public void consumeOrderMessages() { Object message messageQueue.receiveMessage(order:queue); if (message ! null) { Order order (Order) message; System.out.println(Processing order: order.getId()); // 处理订单 } } }最佳实践1. 性能优化使用连接池配置合理的连接池大小使用 Pipeline批量执行命令减少网络往返使用 Lua 脚本原子性执行多个命令合理设置过期时间避免内存泄漏使用合适的数据结构根据业务场景选择合适的数据结构2. 可靠性保证持久化配置配置合适的持久化策略高可用使用主从复制和哨兵模式集群使用 Redis Cluster 集群错误处理合理处理 Redis 连接错误监控监控 Redis 性能和状态3. 安全最佳实践设置密码为 Redis 设置密码限制访问限制 Redis 的网络访问使用 SSL启用 SSL 加密避免使用 KEYS 命令在生产环境中避免使用 KEYS 命令定期备份定期备份 Redis 数据实战案例1. 缓存使用Service public class ProductService { Autowired private ProductRepository productRepository; Cacheable(value products, key #id) public Product findById(Long id) { return productRepository.findById(id).orElse(null); } CachePut(value products, key #product.id) public Product save(Product product) { return productRepository.save(product); } CacheEvict(value products, key #id) public void deleteById(Long id) { productRepository.deleteById(id); } Cacheable(value products, key #category) public ListProduct findByCategory(String category) { return productRepository.findByCategory(category); } }2. 分布式锁Service public class InventoryService { Autowired private InventoryRepository inventoryRepository; Autowired private RedisLockService redisLockService; public boolean deductInventory(Long productId, int quantity) { String lockKey inventory:lock: productId; String lockValue UUID.randomUUID().toString(); try { if (redisLockService.tryLock(lockKey, lockValue, 5, TimeUnit.SECONDS)) { // 获取库存 Inventory inventory inventoryRepository.findByProductId(productId); if (inventory.getQuantity() quantity) { // 扣减库存 inventory.setQuantity(inventory.getQuantity() - quantity); inventoryRepository.save(inventory); return true; } else { return false; } } else { throw new RuntimeException(Failed to acquire lock); } } catch (Exception e) { throw new RuntimeException(e); } finally { redisLockService.unlock(lockKey, lockValue); } } }3. 会话管理Controller public class UserController { Autowired private HttpSession session; PostMapping(/login) public String login(RequestParam String username, RequestParam String password) { // 验证用户名和密码 if (validateCredentials(username, password)) { // 存储用户信息到会话 session.setAttribute(user, username); return redirect:/home; } else { return redirect:/login?errortrue; } } GetMapping(/home) public String home(Model model) { // 从会话中获取用户信息 String user (String) session.getAttribute(user); if (user null) { return redirect:/login; } model.addAttribute(user, user); return home; } GetMapping(/logout) public String logout(HttpSession session) { // invalidate 会话 session.invalidate(); return redirect:/login; } private boolean validateCredentials(String username, String password) { // 验证逻辑 return true; } }常见问题与解决方案1. 内存问题问题Redis 内存使用过高解决方案合理设置过期时间使用合适的数据结构定期清理无用数据监控内存使用情况2. 连接问题问题Redis 连接失败解决方案检查网络连接检查 Redis 服务器状态配置合理的连接池实现重试机制3. 性能问题问题Redis 性能下降解决方案使用 Pipeline使用 Lua 脚本优化数据结构监控 Redis 性能指标4. 数据一致性问题Redis 与数据库数据不一致解决方案使用事务实现最终一致性合理的缓存更新策略定期同步数据5. 安全问题问题Redis 安全漏洞解决方案设置密码限制访问使用 SSL定期更新 Redis 版本总结Spring Boot 与 Redis 的集成是构建高性能、可靠的应用的重要方式。通过合理使用 Redis 的各种功能我们可以实现缓存、会话管理、分布式锁、消息队列等功能。在实际项目中我们应该了解 Redis 的核心概念和 Spring Data Redis 的组件遵循最佳实践如性能优化、可靠性保证和安全最佳实践合理处理常见问题如内存问题、连接问题、性能问题、数据一致性和安全问题不断学习和探索 Redis 的新特性和最佳实践

相关新闻