Spring Boot 整合 Redis 实战
一、整合准备:环境与依赖
1. 技术栈说明
- Spring Boot 版本:3.1.2(兼容 Java 17+)
- Redis 服务器:Redis 7.0+(本地部署或 Docker 容器)
- Maven 依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId> </dependency> <!-- 可选: Lettuce连接池(默认)或Jedis --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> <!-- 缓存注解支持 --> </dependency>
2. 启动 Redis 服务
- 本地启动:下载 Redis 安装包,执行redis-server
- Docker 启动:
docker run -d --name redis-server -p 6379:6379 redis:7.0-alpine
二、基础整合:配置与核心组件
1. 基础配置(application.yml)
spring:redis:host: localhost # Redis服务器地址port: 6379 # 端口password: "" # 密码(无密码则留空)database: 0 # 使用的数据库(0-15)lettuce:pool:max-active: 8 # 连接池最大连接数(使用负值表示没有限制)max-idle: 8 # 连接池最大空闲连接min-idle: 0 # 连接池最小空闲连接timeout: 3000ms # 连接超时时间(毫秒)
2. RedisTemplate 配置(自定义序列化)
默认的 JDK 序列化会生成二进制数据,可读性差且效率低,推荐使用 JSON 序列化:
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);// 配置Key序列化(String)template.setKeySerializer(new StringRedisSerializer());// 配置Value序列化(JSON)Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);template.setValueSerializer(jsonSerializer);// 哈希键和值序列化template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(jsonSerializer);return template;}
}
三、实战案例:核心功能实现
案例 1:简单缓存操作(CRUD)
1. 实体类(示例:用户信息)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Long id;private String username;private Integer age;
}
2. 服务层(使用 RedisTemplate)
@Service
public class UserService {private final RedisTemplate<String, Object> redisTemplate;public UserService(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}// 存储数据(带过期时间)public void saveUser(Long userId, User user, long timeout, TimeUnit unit) {String key = "user:" + userId;redisTemplate.opsForValue().set(key, user, timeout, unit);}// 获取数据public User getUser(Long userId) {String key = "user:" + userId;return (User) redisTemplate.opsForValue().get(key);}// 删除数据public void deleteUser(Long userId) {String key = "user:" + userId;redisTemplate.delete(key);}
}
3. 控制器层
@RestController
@RequestMapping("/users")
public class UserController {private final UserService userService;public UserController(UserService userService) {this.userService = userService;}@PostMapping("/{userId}")public void saveUser(@PathVariable Long userId) {User user = new User(userId, "john_doe", 30);userService.saveUser(userId, user, 60, TimeUnit.SECONDS);}@GetMapping("/{userId}")public User getUser(@PathVariable Long userId) {return userService.getUser(userId);}
}
案例 2:使用 Spring Cache 注解简化开发
1. 启用缓存(主类添加注解)
@SpringBootApplication
@EnableCaching // 开启缓存支持
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
2. 服务层(注解驱动)
@Service
public class CacheService {// 缓存方法结果(key自动生成:方法参数+类名+方法名)@Cacheable(value = "products", key = "#productId") public Product getProduct(Long productId) {// 模拟数据库查询return databaseQuery(productId); }// 缓存更新(先更新数据库,再更新缓存)@CachePut(value = "products", key = "#product.id") public Product updateProduct(Product product) {// 更新数据库return databaseUpdate(product);}// 缓存删除(删除指定key的缓存)@CacheEvict(value = "products", key = "#productId") public void deleteProduct(Long productId) {databaseDelete(productId);}
}
案例 3:分布式锁(解决并发问题)
1. 使用 Redisson 实现分布式锁(添加依赖)
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.21.0</version>
</dependency>
2. 配置 Redisson 客户端(application.yml)
spring:redisson:singleServerConfig:address: "redis://localhost:6379"password: ""
3. 服务层(分布式锁示例)
@Service
public class OrderService {private final RedissonClient redissonClient;public OrderService(RedissonClient redissonClient) {this.redissonClient = redissonClient;}public void createOrder(String orderId) {RLock lock = redissonClient.getLock("order_lock:" + orderId);try {// 加锁(默认30秒自动续租)lock.lock(); // 执行业务逻辑(如扣减库存)deductStock(orderId);} finally {lock.unlock(); // 释放锁}}
}
四、高级用法:分布式会话与性能优化
1. 分布式会话管理(Spring Session + Redis)
(1)添加依赖
<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId>
</dependency>
2)配置application.yml
spring:session:store-type: redis # 使用Redis存储会话redis:namespace: session # 会话数据命名空间
(3)效果
- 自动将会话数据存储到 Redis,解决分布式系统中 Session 共享问题
- 支持会话失效时间配置、集群环境下的无缝切换
2. 性能优化技巧
(1)连接池调优
spring:redis:lettuce:pool:max-active: 20 # 根据并发量调整,建议不超过Redis实例的最大连接数(默认10000)max-wait: 100ms # 连接获取最大等待时间
(2)Pipeline 批量操作
List<Object> results = redisTemplate.executePipelined(connection -> {for (Long userId : userIds) {connection.get("user:" + userId.getBytes());}return null;}
);
(3)淘汰策略配置
在 Redis 服务器端配置redis.conf,常用策略:
- allkeys-lru:当内存不足时,淘汰最近最少使用的键(推荐缓存场景)
- volatile-ttl:淘汰剩余过期时间最短的键
五、注意事项与最佳实践
1. 数据持久化
- 启用 RDB 或 AOF 持久化,避免内存数据丢失
- 生产环境建议同时开启 RDB(快照)和 AOF(日志)
2. 缓存穿透与雪崩
- 穿透:使用布隆过滤器(Bloom Filter)过滤无效 key
- 雪崩:设置随机过期时间、启用 Redis 集群主从复制
3. 序列化选择
- 优先使用 JSON 序列化(Jackson/JSONB),避免 JDK 序列化的性能损耗
- 二进制数据可直接使用RedisSerializer<byte[]>
4. 监控与运维
- 监控 Redis 内存使用率(used_memory)、连接数(client_list)
- 使用 Spring Boot Admin 或 Prometheus+Grafana 监控 Redis 性能指标
六、总结
通过 Spring Boot 与 Redis 的整合,我们可以轻松实现高性能缓存、分布式锁、会话共享等关键功能,显著提升系统的并发处理能力和用户体验。实际项目中,需根据场景选择合适的技术方案:
- 简单缓存:直接使用RedisTemplate或 Cache 注解
- 分布式场景:Redisson 实现分布式锁,Spring Session 管理会话
- 高可用:搭建 Redis 集群(主从 + 哨兵 / Cluster 模式)