From 63f220ac7ba9bd6f8247a73f5159a372548745b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=82=E6=A2=A6=E6=8A=80=E6=9C=AF?= <596392912@qq.com> Date: Tue, 18 May 2021 20:40:50 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20mica-redis=20=E4=BC=98=E5=8C=96=20?= =?UTF-8?q?ICacheKey=20=E5=92=8C=20scan=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + README.md | 16 +- mica-captcha/README.md | 2 +- .../dreamlu/mica/redis/cache/CacheKey.java | 12 +- .../dreamlu/mica/redis/cache/ICacheKey.java | 18 ++- .../mica/redis/cache/MicaRedisCache.java | 146 +++++++++--------- 6 files changed, 102 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac6ee3c..7e274881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index a3c31fe5..6ec8a40f 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/mica-captcha/README.md b/mica-captcha/README.md index 82eb4e42..fdf039a7 100644 --- a/mica-captcha/README.md +++ b/mica-captcha/README.md @@ -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. 验证码生成 diff --git a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/CacheKey.java b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/CacheKey.java index 59fc27bf..d2ae32b7 100644 --- a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/CacheKey.java +++ b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/CacheKey.java @@ -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); } } diff --git a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/ICacheKey.java b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/ICacheKey.java index 2d6a43e5..a6ca52f8 100644 --- a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/ICacheKey.java +++ b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/ICacheKey.java @@ -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); } diff --git a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java index 1b51f82b..47bac4bc 100644 --- a/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java +++ b/mica-redis/src/main/java/net/dreamlu/mica/redis/cache/MicaRedisCache.java @@ -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 Redis Documentation: SETEX */ 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 scan(@Nullable String pattern) { - final Set keySet = new HashSet<>(); - scan(pattern, keySet::add); - return keySet; + public Set scan(String pattern) { + return scan(pattern, 100L); } /** * redis scan * * @param pattern 匹配表达式 - * @param count 一次扫描的数量 + * @param count 一次扫描的数量, redis 默认为 10 * @return 扫描结果 */ - public Pair> scan(@Nullable String pattern, @Nullable Long count) { + public Set scan(String pattern, @Nullable Long count) { final Set keySet = new HashSet<>(); - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - return redisTemplate.execute((RedisCallback>>) action -> { - ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() - .match(pattern); - if (count != null) { - builder.count(count); - } - try (Cursor 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 consumer) { - scan(pattern, null, consumer); + public void scan(String pattern, Consumer 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 consumer) { + public void scan(String pattern, @Nullable Long count, Consumer consumer) { RedisSerializer keySerializer = (RedisSerializer) 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 consumer) { redisTemplate.execute((RedisCallback) action -> { ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() .match(pattern); @@ -279,10 +276,7 @@ public class MicaRedisCache { builder.count(count); } try (Cursor 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 sScan(String key, @Nullable String pattern) { - final Set keySet = new HashSet<>(); - sScan(key, pattern, keySet::add); - return keySet; + public Set 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> sScan(String key, @Nullable String pattern, @Nullable Long count) { + public Set sScan(String key, String pattern, @Nullable Long count) { final Set keySet = new HashSet<>(); - RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); - return redisTemplate.execute((RedisCallback>>) action -> { - ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() - .match(pattern); - if (count != null) { - builder.count(count); - } - try (Cursor 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 consumer) { - sScan(key, pattern, null, consumer); + public void sScan(String key, String pattern, Consumer 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 consumer) { + RedisSerializer keySerializer = (RedisSerializer) 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 consumer) { + public void sScanBytes(String key, String pattern, @Nullable Long count, Consumer consumer) { RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); redisTemplate.execute((RedisCallback) action -> { ScanOptions.ScanOptionsBuilder builder = ScanOptions.scanOptions() @@ -359,10 +353,7 @@ public class MicaRedisCache { builder.count(count); } try (Cursor 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 loader) { RedisSerializer keySerializer = (RedisSerializer) redisTemplate.getKeySerializer(); @@ -524,6 +515,13 @@ public class MicaRedisCache { return redisTemplate.hasKey(key); } + /** + * 检查给定 key 是否存在。 + */ + public Boolean exists(CacheKey cacheKey) { + return exists(cacheKey.getKey()); + } + /** * 从当前数据库中随机返回(不删除)一个 key 。 */ -- GitLab