redis-cache

对象缓存 RedissonClient / [你的RedisUtils]

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "redis-cache" with this command: npx skills add xu-cell/ai-engineering-init/xu-cell-ai-engineering-init-redis-cache

Redis 缓存开发指南

快速索引

功能 工具类/注解 说明

对象缓存 RedissonClient / [你的RedisUtils]

基于 Redisson

Spring Cache @Cacheable/@CachePut/@CacheEvict

声明式缓存

分布式锁 redissonClient.getLock()

需注入 RedissonClient

限流控制 Redisson RRateLimiter

基于 Redisson

原子操作 Redisson RAtomicLong

原子递增/递减

发布订阅 Redisson RTopic

消息通信

一、Redisson 基础操作

1.1 基础缓存操作

import org.redisson.api.RedissonClient; import org.redisson.api.RBucket;

@Service @RequiredArgsConstructor public class CacheService {

private final RedissonClient redissonClient;

// 设置缓存
public void set(String key, Object value, Duration ttl) {
    RBucket<Object> bucket = redissonClient.getBucket(key);
    bucket.set(value, ttl);
}

// 获取缓存
public <T> T get(String key) {
    RBucket<T> bucket = redissonClient.getBucket(key);
    return bucket.get();
}

// 删除缓存
public boolean delete(String key) {
    return redissonClient.getBucket(key).delete();
}

// 判断是否存在
public boolean exists(String key) {
    return redissonClient.getBucket(key).isExists();
}

// 不存在时设置(原子操作)
public boolean setIfAbsent(String key, Object value, Duration ttl) {
    RBucket<Object> bucket = redissonClient.getBucket(key);
    return bucket.trySet(value, ttl);
}

}

1.2 集合操作

// List RList<String> list = redissonClient.getList("myList"); list.addAll(dataList); List<String> result = list.readAll();

// Set RSet<String> set = redissonClient.getSet("mySet"); set.addAll(dataSet); Set<String> result = set.readAll();

// Map RMap<String, Object> map = redissonClient.getMap("myMap"); map.putAll(dataMap); map.put("key3", "value3"); Object value = map.get("key1");

1.3 发布订阅

// 发布消息 RTopic topic = redissonClient.getTopic("notification:channel"); topic.publish(messageObj);

// 订阅消息 RTopic topic = redissonClient.getTopic("notification:channel"); topic.addListener(MessageDTO.class, (channel, msg) -> { // 处理消息 });

1.4 限流控制

import org.redisson.api.RRateLimiter; import org.redisson.api.RateType; import org.redisson.api.RateIntervalUnit;

RRateLimiter limiter = redissonClient.getRateLimiter("api:limit:user:" + userId); // 每10秒最多100个请求 limiter.trySetRate(RateType.OVERALL, 100, 10, RateIntervalUnit.SECONDS);

if (!limiter.tryAcquire()) { throw new 你的异常类; }

1.5 原子操作

RAtomicLong counter = redissonClient.getAtomicLong("counter:view"); counter.set(0L); long value = counter.get(); long newVal = counter.incrementAndGet(); long newVal = counter.decrementAndGet();

二、Spring Cache 注解使用规范

@Cacheable - 查询缓存

@Cacheable(value = "dictData", key = "#dictType") @Override public List<DictDataVo> listDictDataByType(String dictType) { if (dictType == null || dictType.isBlank()) { return Collections.emptyList(); } List<DictData> dictDataList = dictDataMapper.selectByType(dictType); if (dictDataList.isEmpty()) { return Collections.emptyList(); // 返回空列表防止缓存穿透 } return dictDataList.stream() .map(d -> BeanUtil.copyProperties(d, DictDataVo.class)) .toList(); }

@CachePut / @CacheEvict

@CachePut(value = "dictData", key = "#bo.dictType") public List<DictDataVo> insertDictType(DictTypeBo bo) { ... }

@CacheEvict(value = "dictData", key = "#dictType") public void deleteDictType(String dictType) { ... }

@CacheEvict(value = "dictData", allEntries = true) public void clearAllDictCache() { ... }

返回值禁止使用不可变集合

// ❌ 禁止! @Cacheable 返回值序列化失败 return List.of(data1, data2); return Set.of("admin", "user"); return Map.of("key1", "value1");

// ✅ 正确:使用可变集合 List<DictDataVo> result = new ArrayList<>(); result.add(data1); return result;

三、CacheNames 命名规范

推荐格式

cacheNames#ttl#maxIdleTime#maxSize

  • ttl: 过期时间(0=不过期,默认0)
  • maxIdleTime: 最大空闲时间(0=不检测,默认0)
  • maxSize: 最大条数(0=无限,默认0)

"test#60s" // 60秒过期 "test#0#60s" // 不过期,60秒空闲清理 "test#0#1m#1000" // 不过期,1分钟空闲,最大1000条 "test#1h#0#500" // 1小时过期,最大500条

常量定义示例

public interface CacheNames { String SYS_CONFIG = "sys_config"; String SYS_DICT = "sys_dict"; String SYS_USER_NAME = "sys_user_name#30d"; String SYS_DEPT = "sys_dept#30d"; }

四、分布式锁

直接注入 RedissonClient 使用。

@Service @RequiredArgsConstructor public class OrderServiceImpl {

private final RedissonClient redissonClient;

public void submitOrder(OrderBo orderBo) {
    String lockKey = "lock:submit:order:" + orderBo.getUserId();
    RLock lock = redissonClient.getLock(lockKey);

    try {
        boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
        if (!locked) {
            throw new [你的异常类]("请勿重复提交订单");
        }
        try {
            orderMapper.insert(orderBo);
        } finally {
            if (lock.isLocked() &#x26;&#x26; lock.isHeldByCurrentThread()) {
                lock.unlock();  // 必须在 finally 中释放
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new [你的异常类]("订单提交被中断");
    }
}

}

五、缓存 Key 命名规范

格式:{业务模块}:{功能}:{具体标识}

示例: user:info:123 user:roles:123 user:permissions:123 dict:data:sys_user_sex order:info:20240101001 order:status:20240101001 lock:order:20240101001 lock:stock:123 lock:submit:order:456 limit:api:user:123 limit:sms:18888888888

六、注意事项速查

  • @Cacheable 返回值不能使用不可变集合(List.of()、Set.of()、Map.of())

  • 分布式锁必须在 finally 中释放

  • 返回空列表而不是 null,防止缓存穿透

  • 设置随机过期时间偏移,避免缓存雪崩

  • 热点数据用分布式锁 + 双重检查,防止缓存击穿

  • keys() 模式匹配要谨慎,生产环境避免大范围扫描

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

leniu-code-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

leniu-api-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

dev

No summary provided by upstream source.

Repository SourceNeeds Review