提交 63f220ac 编写于 作者: 如梦技术's avatar 如梦技术 🐛

mica-redis 优化 ICacheKey 和 scan。

上级 40516d95
......@@ -7,6 +7,7 @@
- :sparkles: mica-jetcache 完善 metrics 待续 #37 #I3PX2K
- :sparkles: mica-caffeine 添加不支持自定义 Caffeine bean 提示。
- :sparkles: mica-core R 添加 throwOn 系列方法。
- :sparkles: mica-redis 优化 ICacheKey 和 scan。
- :bug: mica-logging 修复 LoggingInitializer Spring boot 2.4.x 失效的问题。
- :arrow_up: 升级 druid 到 1.2.6
......
......@@ -23,16 +23,17 @@
| 2.4.5 | mica 2.4.x | 2.4.x | 2020 |
| 2.1.1-GA | mica 2.0.x~2.1.x | 2.2.x ~ 2.3.x | Hoxton |
## 版本号说明
`release` 版本号格式为 `x.x.x`, 基本上保持跟 `Spring boot` 一致。
`snapshots` 版本号格式为 `x.x.x-SNAPSHOT``snapshots` 版每次 `push` 后会自动构建。
## mica 生态
- mica-auto (Spring boot starter 利器): https://gitee.com/596392912/mica-auto
- mica-weixin(jfinal weixin 的 spring boot starter)https://gitee.com/596392912/mica-weixin
- mica-mqtt(基于 t-io 实现的 mqtt组件)https://gitee.com/596392912/mica-mqtt
- mica-weixin(jfinal weixin 的 spring boot starter): https://gitee.com/596392912/mica-weixin
- mica-mqtt(基于 t-io 实现的 mqtt组件): https://gitee.com/596392912/mica-mqtt
- Spring cloud 微服务 http2 方案(h2c): https://gitee.com/596392912/spring-cloud-java11
## 版本号说明
`release` 版本号格式为 `x.x.x-GA`,响应 `冷神` 的吐槽,改短了一点。
`snapshots` 版本号格式为 `x.x.x-SNAPSHOT``snapshots` 版每次提交后会自动构建。
- mica-security(mica权限系统 vue 改造中): https://gitee.com/596392912/mica-security
## 已知问题
lombok 生成的 method 问题:https://github.com/rzwitserloot/lombok/issues/1861
......@@ -69,7 +70,6 @@ LGPL 是 GPL 的一个为主要为类库使用设计的开源协议。和 GPL
* `bladex` 完整的线上解决方案(企业生产必备):https://bladex.vip
## 相关链接
* `示例项目`[https://github.com/lets-mica/mica-example](https://github.com/lets-mica/mica-example)
* mica 源码 Github:[https://github.com/lets-mica](https://github.com/lets-mica)
* mica 源码 Gitee(码云):[https://gitee.com/596392912/mica](https://gitee.com/596392912/mica)
* mica 性能压测:[https://github.com/lets-mica/mica-jmh](https://github.com/lets-mica/mica-jmh)
......
......@@ -5,7 +5,7 @@
![数学验证码02](../docs/images/0702.m.jpg)
![随机数验证码03](../docs/images/0703.r.jpg)
![随机数验证码04](../docs/images/0703.r.jpg)
![随机数验证码04](../docs/images/0704.r.jpg)
## 功能和特点
1. 验证码生成
......
......@@ -16,8 +16,8 @@
package net.dreamlu.mica.redis.cache;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.springframework.lang.Nullable;
......@@ -30,20 +30,22 @@ import java.time.Duration;
*/
@Getter
@ToString
@AllArgsConstructor
@RequiredArgsConstructor
public class CacheKey {
/**
* redis key
*/
private String key;
private final String key;
/**
* 超时时间 秒
*/
@Nullable
private Duration expire;
private final Duration expire;
public CacheKey(String key) {
this.key = key;
this(key, null);
}
}
......@@ -53,15 +53,23 @@ public interface ICacheKey {
* @param suffix 参数
* @return cache key
*/
default CacheKey getKey(Object... suffix) {
default String getKeyStr(Object... suffix) {
String prefix = this.getPrefix();
// 拼接参数
String key;
if (ObjectUtil.isEmpty(suffix)) {
key = prefix;
} else {
key = prefix.concat(StringUtil.join(suffix, StringPool.COLON));
return prefix;
}
return prefix.concat(StringUtil.join(suffix, StringPool.COLON));
}
/**
* 组装 cache key
*
* @param suffix 参数
* @return cache key
*/
default CacheKey getKey(Object... suffix) {
String key = this.getKeyStr(suffix);
Duration expire = this.getExpire();
return expire == null ? new CacheKey(key) : new CacheKey(key, expire);
}
......
......@@ -17,7 +17,6 @@
package net.dreamlu.mica.redis.cache;
import lombok.Getter;
import net.dreamlu.mica.core.tuple.Pair;
import net.dreamlu.mica.core.utils.CollectionUtil;
import net.dreamlu.mica.core.utils.Exceptions;
import org.springframework.data.redis.core.*;
......@@ -97,10 +96,10 @@ public class MicaRedisCache {
/**
* Set the {@code value} and expiration {@code timeout} for {@code key}.
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @param timeout the key expiration timeout.
* @param unit must not be {@literal null}.
* @param unit must not be {@literal null}.
* @see <a href="https://redis.io/commands/setex">Redis Documentation: SETEX</a>
*/
public void setEx(String key, Object value, long timeout, TimeUnit unit) {
......@@ -215,63 +214,61 @@ public class MicaRedisCache {
}
/**
* redis scan
* redis scan,count 默认 100
*
* @param pattern 匹配表达式
* @return 扫描结果
*/
public Set<String> scan(@Nullable String pattern) {
final Set<String> keySet = new HashSet<>();
scan(pattern, keySet::add);
return keySet;
public Set<String> scan(String pattern) {
return scan(pattern, 100L);
}
/**
* redis scan
*
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param count 一次扫描的数量, redis 默认为 10
* @return 扫描结果
*/
public Pair<Long, Set<String>> scan(@Nullable String pattern, @Nullable Long count) {
public Set<String> scan(String pattern, @Nullable Long count) {
final Set<String> keySet = new HashSet<>();
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
return redisTemplate.execute((RedisCallback<Pair<Long, Set<String>>>) action -> {
ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions()
.match(pattern);
if (count != null) {
builder.count(count);
}
try (Cursor<byte[]> cursor = action.scan(builder.build())) {
cursor.forEachRemaining((item) -> keySet.add(keySerializer.deserialize(item)));
return Pair.create(cursor.getPosition(), keySet);
} catch (IOException e) {
throw Exceptions.unchecked(e);
}
});
scan(pattern, count, keySet::add);
return keySet;
}
/**
* redis scan
* redis scan, count 默认 100
*
* @param pattern 匹配表达式
* @param pattern 匹配表达式
* @param consumer 消费者
* @return 扫描结果
*/
public void scan(@Nullable String pattern, Consumer<String> consumer) {
scan(pattern, null, consumer);
public void scan(String pattern, Consumer<String> consumer) {
scan(pattern, 100L, consumer);
}
/**
* redis scan
*
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param consumer 消费者
* @return 扫描结果
*/
public void scan(@Nullable String pattern, @Nullable Long count, Consumer<String> consumer) {
public void scan(String pattern, @Nullable Long count, Consumer<String> consumer) {
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
scanBytes(pattern, count, (bytes) -> consumer.accept(keySerializer.deserialize(bytes)));
}
/**
* redis scan
*
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param consumer 消费者
* @return 扫描结果
*/
public void scanBytes(String pattern, @Nullable Long count, Consumer<byte[]> consumer) {
redisTemplate.execute((RedisCallback<Object>) action -> {
ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions()
.match(pattern);
......@@ -279,10 +276,7 @@ public class MicaRedisCache {
builder.count(count);
}
try (Cursor<byte[]> cursor = action.scan(builder.build())) {
cursor.forEachRemaining((item) -> {
String redisKey = keySerializer.deserialize(item);
consumer.accept(redisKey);
});
cursor.forEachRemaining(consumer);
} catch (IOException e) {
throw Exceptions.unchecked(e);
}
......@@ -291,66 +285,66 @@ public class MicaRedisCache {
}
/**
* redis sscan
* redis sscan,count 默认 100
*
* @param key key
* @param key key
* @param pattern 匹配表达式
* @return 扫描结果
*/
public Set<String> sScan(String key, @Nullable String pattern) {
final Set<String> keySet = new HashSet<>();
sScan(key, pattern, keySet::add);
return keySet;
public Set<String> sScan(String key, String pattern) {
return sScan(key, pattern, 100L);
}
/**
* redis sscan
*
* @param key key
* @param key key
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @return 扫描结果
*/
public Pair<Long, Set<String>> sScan(String key, @Nullable String pattern, @Nullable Long count) {
public Set<String> sScan(String key, String pattern, @Nullable Long count) {
final Set<String> keySet = new HashSet<>();
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
return redisTemplate.execute((RedisCallback<Pair<Long, Set<String>>>) action -> {
ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions()
.match(pattern);
if (count != null) {
builder.count(count);
}
try (Cursor<byte[]> cursor = action.sScan(keySerializer.serialize(key), builder.build())) {
cursor.forEachRemaining((item) -> keySet.add(keySerializer.deserialize(item)));
return Pair.create(cursor.getPosition(), keySet);
} catch (IOException e) {
throw Exceptions.unchecked(e);
}
});
sScan(key, pattern, count, keySet::add);
return keySet;
}
/**
* redis sscan
*
* @param key key
* @param pattern 匹配表达式
* @param consumer consumer
* @param key key
* @param pattern 匹配表达式
* @param consumer consumer
* @return 扫描结果
*/
public void sScan(String key, @Nullable String pattern, Consumer<String> consumer) {
sScan(key, pattern, null, consumer);
public void sScan(String key, String pattern, Consumer<String> consumer) {
sScan(key, pattern, 100L, consumer);
}
/**
* redis sscan
*
* @param key key
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param consumer consumer
* @param key key
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param consumer consumer
* @return 扫描结果
*/
public void sScan(String key, String pattern, @Nullable Long count, Consumer<String> consumer) {
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
sScanBytes(key, pattern, count, (bytes) -> consumer.accept(keySerializer.deserialize(bytes)));
}
/**
* redis sscan
*
* @param key key
* @param pattern 匹配表达式
* @param count 一次扫描的数量
* @param consumer consumer
* @return 扫描结果
*/
public void sScan(String key, @Nullable String pattern, @Nullable Long count, Consumer<String> consumer) {
public void sScanBytes(String key, String pattern, @Nullable Long count, Consumer<byte[]> consumer) {
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
redisTemplate.execute((RedisCallback<Object>) action -> {
ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions()
......@@ -359,10 +353,7 @@ public class MicaRedisCache {
builder.count(count);
}
try (Cursor<byte[]> cursor = action.sScan(keySerializer.serialize(key), builder.build())) {
cursor.forEachRemaining((item) -> {
String redisKey = keySerializer.deserialize(item);
consumer.accept(redisKey);
});
cursor.forEachRemaining(consumer);
} catch (IOException e) {
throw Exceptions.unchecked(e);
}
......@@ -496,9 +487,9 @@ public class MicaRedisCache {
/**
* 获取记数器的值,用于初始化获取 incr、incrBy 的值
*
* @param key key
* @param key key
* @param seconds 超时时间
* @param loader 加载器
* @param loader 加载器
*/
public Long getCounter(String key, long seconds, Supplier<Long> loader) {
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
......@@ -524,6 +515,13 @@ public class MicaRedisCache {
return redisTemplate.hasKey(key);
}
/**
* 检查给定 key 是否存在。
*/
public Boolean exists(CacheKey cacheKey) {
return exists(cacheKey.getKey());
}
/**
* 从当前数据库中随机返回(不删除)一个 key 。
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册