# 蘑菇工具箱-Cache
**Repository Path**: kinokoyoo/toolbox-cache
## Basic Information
- **Project Name**: 蘑菇工具箱-Cache
- **Description**: 基于redisson和caffeine二次开发的工具库,致力于提供缓存通用解决方案;
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-11-26
- **Last Updated**: 2024-02-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: redisson, Redis, Caffeine, Java
## README
# 蘑菇工具箱-Cache
## 介绍
基于redisson和caffeine二次开发的工具库,致力于提供缓存通用解决方案;
内容包含如下:
- 常用缓存注解
- 分布式锁
- 限流器
- Lua脚本执行器
- Redis常用数据结构指令
功能支持:
- 缓存双删
- 布隆过滤器
- 软布隆
## 版本
- jdk:1.8+
- redisson:3.25.2
- spring aop:2.7.18
- caffeine:3.1.8
## 快速开始
### 1.引入依赖
```xml
cn.kinoko
cache-spring-boot-starter
1.0-SNAPSHOT
```
### 2.在yaml中加入配置
```yaml
spring:
redisson:
file: classpath:redisson.yaml
type-match: true
enable-prefix: false
bloom-filter:
enable: true
key: bloom-filter
tolerate-error: 0.05
release-retry: 10
```
- `file`:配置文件地址(必填)
- `type-match`:是否开启Java对象存储缓存的最佳类型匹配(可选)
- `enable-prefix`:是否开启key前缀,使用服务名称和环境拼接(可选)
- `bloom-filter`:布隆过滤器配置(可选)
- `enable`:是否开启布隆过滤器(可选)
- `key`:布隆过滤器key(可选)
- `tolerate-error`:布隆过滤器容错率(可选)
- `release-retry`:软布隆重试时间间隔(分钟)(可选)
### 3.创建redisson配置文件
file配置的路径,如第2步配置就是放在resource目录下
```yaml
singleServerConfig:
address: "redis://127.0.0.1:6379" # 地址
clientName: null # 客户端名称
password: null # 密码
database: 0 # 数据库索引
idleConnectionTimeout: 10000 # 连接空闲超时时间
connectTimeout: 10000 # 连接超时时间
timeout: 3000 # 命令执行超时时间
retryAttempts: 3 # 重试次数
retryInterval: 1500 # 重试间隔时间
subscriptionsPerConnection: 5 # 订阅连接池大小
subscriptionConnectionMinimumIdleSize: 1 # 订阅连接最小空闲连接数
subscriptionConnectionPoolSize: 50 # 订阅连接池大小
connectionMinimumIdleSize: 24 # 连接最小空闲连接数
connectionPoolSize: 64 # 连接池大小
dnsMonitoringInterval: 5000 # DNS监控间隔时间
threads: 16 # 线程池大小
nettyThreads: 32 # Netty线程池大小
codec: ! {} # 编解码器
transportMode: "NIO" # 连接模式
```
> 参考redisson官方给出的配置,这是单机的,也有集群的配置
>
> 官网:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#21-%E7%A8%8B%E5%BA%8F%E5%8C%96%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95
## 使用说明
### @Cacheable
**说明**:缓存注解(无缓存插入,有缓存返回)
**参数**:
```java
// 缓存的key
String key() default "";
// 缓存的key参数
String params() default "";
// 不加入缓存的条件
String unless() default "";
// 锁的过期时间
int expire() default -1;
// 时间单位
TimeUnit timeUnit() default TimeUnit.SECONDS;
```
**示例**:
```java
@Cacheable(key = "user", params = "#id")
@GetMapping("/test")
public Object test(@RequestParam Long id, @RequestParam String name) {
// do something
return obj;
}
```
### @CachePut
**说明**:插入缓存注解(仅插入)
**参数**:
```java
// 缓存的key
String key() default "";
// 缓存的key参数
String params() default "";
// 不加入缓存的条件
String unless() default "";
// 锁的过期时间
int expire() default -1;
// 时间单位
TimeUnit timeUnit() default TimeUnit.SECONDS;
```
**示例**
```java
@CachePut(key = "user", params = "#id")
@GetMapping("/test")
public Object test(@RequestParam Long id, @RequestParam String name) {
// do something
return obj;
}
```
### @CacheEvict
**说明**:删除缓存注解
**参数**:
```java
// 缓存的key
String key() default "";
// 缓存的key参数
String params() default "";
// 不加入缓存的条件
String unless() default "";
// 双删策略等待时间(ms)
int waitTime() default -1;
```
> 当设置了waitTime时会启用缓存双删策略
**示例**
```java
@CacheEvict(key = "user", params = "#id", waitTime = 500)
@GetMapping("/update")
public Object update(@RequestParam Long id, @RequestParam String name) {
// do something
return obj;
}
```
### @DistributedLock
**说明**:分布式锁注解
**参数**:
```java
// 锁的key
String key() default "";
// 锁的key参数
String params() default "";
// 锁的过期时间
int expire() default 10;
// 自动释放锁
boolean autoRelease() default true;
// 异常描述
String errorDesc() default "系统繁忙,请稍后再试";
// 等待时间
int waitTime() default 1;
// 时间单位
TimeUnit timeUnit() default TimeUnit.SECONDS;
```
**示例**
```java
@DistributedLock(key = "lock_test", params = "#info.id")
@PostMapping("/lock")
public String lock(@RequestBody Info info) {
return "success";
}
```
### @RateLimiter
**说明**:分布式限流器注解
**参数**:
```java
// 限流key
String key() default "";
// 限流粒度
Granularity granularity() default Granularity.NO_LIMIT;
// 限流错误描述
String errorDesc() default "网络繁忙,请稍后再试";
// 限流类型
RateType rateType() default RateType.OVERALL;
// 速率(产生几个令牌)
int rate() default 1;
// 速率间隔
int rateInterval() default 1;
// 限流时间单位
RateIntervalUnit intervalUnit() default RateIntervalUnit.SECONDS;
// 限流等待时间
int timeout() default -1;
// 时间单位
TimeUnit timeUnit() default TimeUnit.SECONDS;
enum Granularity {
/**
* 不限制粒度
*/
NO_LIMIT,
/**
* 按用户限流
*/
USER,
/**
* 按IP限流
*/
IP
}
```
> granularity参数正在开发,尝试切入自定义代码块来适配各类项目
**示例**
```java
// 10s产生3个令牌
@RateLimiter(rate = 3, rateInterval = 10, intervalUnit = RateIntervalUnit.SECONDS)
@GetMapping("/limiter")
public String limiter() {
return "success";
}
```
### RedisService
说明:基础api
```java
/**
* 获取所有匹配的key
* command: keys pattern
*
* @param pattern 匹配的key
* @return 匹配的key
*/
Iterable getKeys(String pattern);
/**
* 设置缓存
* command: set key value
*
* @param key key
* @param value value
*/
void set(String key, V value);
/**
* 设置缓存
* command: set key value [ex seconds] [px milliseconds]
*
* @param key key
* @param value value
* @param expire 过期时间
* @param timeUnit 时间单位
*/
void set(String key, Object value, long expire, TimeUnit timeUnit);
/**
* 批量设置多个缓存
* command: mset key value [key value …]
*
* @param temps temps
*/
void multiSet(Map temps);
/**
* 获取缓存
* command: get key
*
* @param key key
* @return value
*/
V get(String key);
/**
* 获取所有匹配 pattern 的缓存key 对应的缓存值
* 此方法 谨慎使用
*
* @param pattern pattern
* @return 匹配的缓存值
*/
Set getAll(String pattern);
/**
* 获取缓存过期时间
* command: ttl key
*
* @param key key
* @return 剩余时间
*/
Long ttl(String key);
/**
* 删除缓存
* command: del key
*
* @param key key
* @return 是否删除成功
*/
boolean del(String key);
/**
* 删除所有匹配 pattern 的缓存key
* command: del key
*
* @param pattern pattern
*/
void delAll(String pattern);
/**
* 获取Map
* command: hset key
*
* @param key key
* @param expireTime 过期时间
* @return Map
*/
RMap getMap(String key, Duration expireTime);
/**
* 获取Map
* command: hset key
*
* @param key key
* @return Map
*/
RMap getMap(String key);
/**
* Map中是否存在field
* command: hexists key field
*
* @param key key
* @param field field
* @return 是否存在
*/
boolean hasMapKey(String key, K field);
/**
* 获取Map中的所有field
* command: hkeys key
*
* @param key key
* @return field集合
*/
Set