一、环境准备与依赖配置
1.1 添加Maven依赖
xml
<!-- Spring Boot Redis Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- JSON序列化支持 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 测试支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
1.2 基础配置
yaml
# application.yml
spring:
redis:
# Redis服务器地址
host: localhost
# Redis服务器连接端口
port: 6379
# Redis数据库索引(默认为0)
database: 0
# Redis服务器连接密码(默认为空)
password:
# 连接超时时间
timeout: 2000ms
# 连接池配置
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
# 集群配置(如果需要)
# cluster:
# nodes:
# - 127.0.0.1:7001
# - 127.0.0.1:7002
# - 127.0.0.1:7003
二、Redis配置类详解
2.1 基础配置类
java
@Configuration
@EnableCaching
public class RedisConfig {
/**
* 配置RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置序列化方式
Jackson2JsonRedisSerializer<Object> serializer =
new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(
mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
);
serializer.setObjectMapper(mapper);
// 设置key和value的序列化规则
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
/**
* 配置缓存管理器
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
// 设置默认过期时间
.entryTtl(Duration.ofMinutes(30))
// 不缓存空值
.disableCachingNullValues()
// 设置key序列化方式
.serializeKeysWith(
RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
// 设置value序列化方式
.serializeValuesWith(
RedisSerializationContext.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
// 对不同的缓存命名空间设置不同的过期时间
.withInitialCacheConfigurations(getCacheConfigurations())
.build();
}
private Map<String, RedisCacheConfiguration> getCacheConfigurations() {
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
// 用户缓存1小时过期
configMap.put("user", RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)));
// 商品缓存10分钟过期
configMap.put("product", RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)));
return configMap;
}
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
Jackson2JsonRedisSerializer<Object> serializer =
new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(
mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
);
serializer.setObjectMapper(mapper);
return serializer;
}
}
2.2 高级配置:多种序列化方式
java
@Configuration
public class RedisSerializerConfig {
/**
* 针对String操作的RedisTemplate
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
return new StringRedisTemplate(factory);
}
/**
* 针对JSON操作的RedisTemplate
*/
@Bean
public RedisTemplate<String, Object> jsonRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
GenericJackson2JsonRedisSerializer serializer =
new GenericJackson2JsonRedisSerializer();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
三、Redis工具类封装
3.1 通用Redis工具类
java
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// ============================= Common =============================
/**
* 指定缓存失效时间
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取过期时间
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*/
public boolean delete(String key) {
try {
return redisTemplate.delete(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 批量删除缓存
*/
public long delete(Collection<String> keys) {
try {
Long count = redisTemplate.delete(keys);
return count == null ? 0 : count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ============================ String =============================
/**
* 普通缓存获取
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// =============================== Hash ===============================
/**
* HashGet
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// =============================== List ===============================
/**
* 获取list缓存的内容
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存并设置过期时间
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// =============================== Set ===============================
/**
* 根据key获取Set中的所有值
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将数据放入set缓存
*/
public boolean sSet(String key, Object... values) {
try {
redisTemplate.opsForSet().add(key, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// =============================== ZSet ===============================
/**
* 向ZSet添加元素
*/
public boolean zAdd(String key, Object value, double score) {
try {
return redisTemplate.opsForZSet().add(key, value, score);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取ZSet排名
*/
public Set<Object> zRange(String key, long start, long end) {
try {
return redisTemplate.opsForZSet().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
3.2 分布式锁工具类
java
@Component
public class RedisLockUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String LOCK_PREFIX = "lock:";
private static final long DEFAULT_EXPIRE = 30000; // 30秒
private static final long DEFAULT_WAIT_TIME = 10000; // 10秒
/**
* 尝试获取分布式锁
*/
public boolean tryLock(String lockKey, String requestId) {
return tryLock(lockKey, requestId, DEFAULT_EXPIRE);
}
/**
* 尝试获取分布式锁(自定义过期时间)
*/
public boolean tryLock(String lockKey, String requestId, long expire) {
String key = LOCK_PREFIX + lockKey;
// 使用SET NX EX命令保证原子性
Boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
byte[] keyBytes = serializer.serialize(key);
byte[] valueBytes = serializer.serialize(requestId);
// SET key value NX EX timeout
return connection.set(keyBytes, valueBytes,
Expiration.milliseconds(expire),
RedisStringCommands.SetOption.SET_IF_ABSENT);
});
return Boolean.TRUE.equals(result);
}
/**
* 释放分布式锁
*/
public boolean releaseLock(String lockKey, String requestId) {
String key = LOCK_PREFIX + lockKey;
// Lua脚本保证原子性
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) " +
"else " +
"return 0 " +
"end";
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Long result = redisTemplate.execute(redisScript,
Collections.singletonList(key),
requestId);
return result != null && result > 0;
}
/**
* 阻塞式获取锁
*/
public boolean lock(String lockKey, String requestId) throws InterruptedException {
return lock(lockKey, requestId, DEFAULT_WAIT_TIME, DEFAULT_EXPIRE);
}
public boolean lock(String lockKey, String requestId, long waitTime, long expire)
throws InterruptedException {
long start = System.currentTimeMillis();
while (true) {
if (tryLock(lockKey, requestId, expire)) {
return true;
}
if (System.currentTimeMillis() - start > waitTime) {
return false;
}
// 等待一段时间再重试
Thread.sleep(100);
}
}
}
四、Spring Cache注解使用
4.1 实体类定义
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private String email;
private Integer age;
private Date createTime;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Double price;
private Integer stock;
private String category;
}
4.2 Service层缓存使用
java
@Service
public class UserService {
// 模拟数据库
private Map<Long, User> userDatabase = new HashMap<>();
private AtomicLong idGenerator = new AtomicLong(1);
/**
* 根据ID查询用户 - 使用缓存
* 如果缓存存在,直接返回缓存数据
* 如果缓存不存在,执行方法体,并将结果放入缓存
*/
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
System.out.println("查询数据库,用户ID: " + id);
// 模拟数据库查询耗时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return userDatabase.get(id);
}
/**
* 保存用户 - 同时更新缓存
* 总是执行方法体,并将结果更新到缓存中
*/
@CachePut(value = "user", key = "#user.id")
public User saveUser(User user) {
System.out.println("保存用户到数据库: " + user.getName());
if (user.getId() == null) {
user.setId(idGenerator.getAndIncrement());
}
userDatabase.put(user.getId(), user);
return user;
}
/**
* 删除用户 - 同时清除缓存
*/
@CacheEvict(value = "user", key = "#id")
public void deleteUser(Long id) {
System.out.println("从数据库删除用户: " + id);
userDatabase.remove(id);
}
/**
* 更新用户 - 更新缓存
*/
@CachePut(value = "user", key = "#user.id")
public User updateUser(User user) {
System.out.println("更新用户信息: " + user.getId());
if (userDatabase.containsKey(user.getId())) {
userDatabase.put(user.getId(), user);
return user;
}
throw new RuntimeException("用户不存在");
}
/**
* 获取所有用户 - 列表缓存
*/
@Cacheable(value = "userList")
public List<User> getAllUsers() {
System.out.println("查询所有用户");
return new ArrayList<>(userDatabase.values());
}
/**
* 清除用户列表缓存
*/
@CacheEvict(value = "userList", allEntries = true)
public void clearUserListCache() {
System.out.println("清除用户列表缓存");
}
/**
* 复杂缓存操作 - 同时操作多个缓存
*/
@Caching(
evict = {
@CacheEvict(value = "user", key = "#id"),
@CacheEvict(value = "userList", allEntries = true)
}
)
public void refreshUserCache(Long id) {
System.out.println("刷新用户缓存: " + id);
}
}
@Service
public class ProductService {
private Map<Long, Product> productDatabase = new HashMap<>();
private AtomicLong idGenerator = new AtomicLong(1);
/**
* 条件查询 - 自定义key生成
*/
@Cacheable(value = "product", key = "#name + ':' + #category")
public Product getProductByNameAndCategory(String name, String category) {
System.out.println("查询产品: " + name + ", 分类: " + category);
return productDatabase.values().stream()
.filter(p -> p.getName().equals(name) && p.getCategory().equals(category))
.findFirst()
.orElse(null);
}
/**
* 带条件的缓存
*/
@Cacheable(value = "product", key = "#id", condition = "#id > 10")
public Product getProductWithCondition(Long id) {
System.out.println("查询产品(条件缓存): " + id);
return productDatabase.get(id);
}
/**
* 除非条件的缓存
*/
@Cacheable(value = "product", key = "#id", unless = "#result == null")
public Product getProductWithUnless(Long id) {
System.out.println("查询产品(除非条件): " + id);
return productDatabase.get(id);
}
}
4.3 自定义Key生成器
java
@Component
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getSimpleName());
sb.append(".");
sb.append(method.getName());
sb.append("[");
for (Object param : params) {
if (param != null) {
sb.append(param.toString());
}
sb.append(",");
}
sb.append("]");
return sb.toString();
}
}
// 在配置类中注册自定义Key生成器
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public KeyGenerator customKeyGenerator() {
return new CustomKeyGenerator();
}
// 使用自定义Key生成器
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.computePrefixWith(cacheName -> cacheName + ":")
.serializeKeysWith(
RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
}
}
五、高级特性集成
5.1 发布订阅模式
java
@Component
public class RedisMessageListener implements MessageListener {
private static final Logger logger = LoggerFactory.getLogger(RedisMessageListener.class);
@Override
public void onMessage(Message message, byte[] pattern) {
String channel = new String(pattern);
String body = new String(message.getBody());
logger.info("收到频道[{}]的消息: {}", channel, body);
// 处理不同的消息类型
handleMessage(channel, body);
}
private void handleMessage(String channel, String message) {
switch (channel) {
case "user:register":
logger.info("处理用户注册消息: {}", message);
break;
case "order:create":
logger.info("处理订单创建消息: {}", message);
break;
default:
logger.info("处理未知频道消息: {}", message);
}
}
}
@Component
public class RedisMessagePublisher {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 发布消息
*/
public void publish(String channel, Object message) {
redisTemplate.convertAndSend(channel, message);
}
/**
* 发布用户注册消息
*/
public void publishUserRegister(User user) {
Map<String, Object> message = new HashMap<>();
message.put("userId", user.getId());
message.put("userName", user.getName());
message.put("email", user.getEmail());
message.put("timestamp", System.currentTimeMillis());
publish("user:register", message);
}
/**
* 发布订单创建消息
*/
public void publishOrderCreate(Long orderId, Double amount) {
Map<String, Object> message = new HashMap<>();
message.put("orderId", orderId);
message.put("amount", amount);
message.put("timestamp", System.currentTimeMillis());
publish("order:create", message);
}
}
@Configuration
public class RedisPubSubConfig {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private RedisMessageListener redisMessageListener;
/**
* 配置消息监听容器
*/
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
// 订阅多个频道
container.addMessageListener(redisMessageListener,
Arrays.asList(
new PatternTopic("user:register"),
new PatternTopic("order:create"),
new PatternTopic("system:notification")
));
return container;
}
}
5.2 管道操作
java
@Service
public class PipelineService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 使用管道批量插入数据
*/
public void batchInsertUsers(List<User> users) {
redisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
for (User user : users) {
String key = "user:" + user.getId();
byte[] keyBytes = redisTemplate.getStringSerializer().serialize(key);
byte[] valueBytes = redisTemplate.getValueSerializer().serialize(user);
connection.set(keyBytes, valueBytes);
// 同时设置过期时间
connection.expire(keyBytes, Duration.ofHours(1).getSeconds());
}
return null;
}
});
}
/**
* 批量获取数据
*/
public List<Object> batchGetUsers(List<Long> userIds) {
return redisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
for (Long userId : userIds) {
String key = "user:" + userId;
byte[] keyBytes = redisTemplate.getStringSerializer().serialize(key);
connection.get(keyBytes);
}
return null;
}
});
}
}
5.3 Lua脚本支持
java
@Service
public class LuaScriptService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 库存扣减脚本
private static final String DEDUCT_SCRIPT =
"local current = tonumber(redis.call('get', KEYS[1])) " +
"if current == nil then " +
" return -1 " +
"end " +
"if current < tonumber(ARGV[1]) then " +
" return -2 " +
"end " +
"redis.call('decrby', KEYS[1], ARGV[1]) " +
"return 0";
// 限流脚本
private static final String RATE_LIMIT_SCRIPT =
"local key = KEYS[1] " +
"local limit = tonumber(ARGV[1]) " +
"local window = tonumber(ARGV[2]) " +
"local current = redis.call('get', key) " +
"if current == false then " +
" redis.call('set', key, 1, 'EX', window) " +
" return 1 " +
"elseif tonumber(current) < limit then " +
" redis.call('incr', key) " +
" return 1 " +
"else " +
" return 0 " +
"end";
/**
* 扣减库存 - Lua脚本保证原子性
*/
public boolean deductInventory(String productId, int quantity) {
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptText(DEDUCT_SCRIPT);
script.setResultType(Long.class);
Long result = redisTemplate.execute(script,
Collections.singletonList("inventory:" + productId),
String.valueOf(quantity));
return result == 0;
}
/**
* 限流检查
*/
public boolean rateLimit(String key, int limit, int window) {
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptText(RATE_LIMIT_SCRIPT);
script.setResultType(Long.class);
Long result = redisTemplate.execute(script,
Collections.singletonList("rate_limit:" + key),
String.valueOf(limit),
String.valueOf(window));
return result == 1;
}
}
六、测试类
java
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisIntegrationTest {
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserService userService;
@Autowired
private RedisMessagePublisher messagePublisher;
@Autowired
private RedisLockUtil redisLockUtil;
@Test
public void testBasicOperations() {
// 测试基本操作
redisUtil.set("test:key", "Hello Redis");
String value = (String) redisUtil.get("test:key");
Assert.assertEquals("Hello Redis", value);
}
@Test
public void testCacheAnnotations() {
// 测试缓存注解
User user = new User(1L, "张三", "zhangsan@example.com", 25, new Date());
// 第一次查询,会访问数据库
User result1 = userService.getUserById(1L);
// 第二次查询,应该从缓存获取
User result2 = userService.getUserById(1L);
Assert.assertNotNull(result1);
Assert.assertNotNull(result2);
}
@Test
public void testDistributedLock() throws InterruptedException {
String lockKey = "order:123";
String requestId = UUID.randomUUID().toString();
// 获取锁
boolean locked = redisLockUtil.tryLock(lockKey, requestId);
Assert.assertTrue(locked);
// 释放锁
boolean released = redisLockUtil.releaseLock(lockKey, requestId);
Assert.assertTrue(released);
}
@Test
public void testPubSub() throws InterruptedException {
// 测试发布订阅
User user = new User(1L, "李四", "lisi@example.com", 30, new Date());
messagePublisher.publishUserRegister(user);
// 等待消息处理
Thread.sleep(1000);
}
}
七、配置优化建议
7.1 生产环境配置
yaml
spring:
redis:
host: ${REDIS_HOST:127.0.0.1}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}
timeout: 3000ms
lettuce:
pool:
max-active: 50
max-idle: 20
min-idle: 5
max-wait: 5000ms
shutdown-timeout: 100ms
cache:
redis:
time-to-live: 1h
cache-null-values: false
use-key-prefix: true
key-prefix: "cache:"
7.2 监控配置
java
@Component
public class RedisMetrics {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
/**
* 获取Redis监控信息
*/
public void monitorRedis() {
RedisConnection connection = redisConnectionFactory.getConnection();
try {
Properties info = connection.info();
System.out.println("Redis版本: " + info.getProperty("redis_version"));
System.out.println("已连接客户端数: " + info.getProperty("connected_clients"));
System.out.println("使用内存: " + info.getProperty("used_memory_human"));
System.out.println("命中率: " + info.getProperty("keyspace_hits"));
} finally {
connection.close();
}
}
}
这个完整的Spring Boot集成Redis指南涵盖了从基础配置到高级特性的所有方面,包括缓存注解、分布式锁、发布订阅、管道操作和Lua脚本等。通过这个指南,你可以快速在项目中集成Redis并充分利用其强大功能。
2807

被折叠的 条评论
为什么被折叠?



