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

redis 限流组件毕业.

上级 c3f29084
# redis-plus-redis
redis cache 增强
- redis cache 增强
- 分布式限流组件
## 功能
1. 支持 # 号分隔 cachename 和 超时 timeOut。
示例:
```java
@Cacheable(value = "user#300", key = "#id")
public String selectById(Serializable id) {
log.info("selectById");
return "selectById:" + id;
}
```
## 使用
## 依赖引用
### maven
```xml
<dependency>
......@@ -28,6 +17,18 @@ public String selectById(Serializable id) {
compile("net.dreamlu:redis-plus-redis:${version}")
```
##1. redis cache 增强
1. 支持 # 号分隔 cachename 和 超时 timeOut。
示例:
```java
@Cacheable(value = "user#300", key = "#id")
public String selectById(Serializable id) {
log.info("selectById");
return "selectById:" + id;
}
```
### MicaRedisCache
MicaRedisCache 为简化 redis 使用的 bean。
```java
......@@ -40,7 +41,7 @@ public String findById(Serializable id) {
}
```
## 注意
### 注意
使用 `protostuff` 做的 `redis` 序列化和反序列化。
`protostuff` 默认是根据 Model `属性顺序`进行序列化,如果在`中间插入`或者`删除字段`
......@@ -54,3 +55,24 @@ public String findById(Serializable id) {
| @Tag(1) | Model `属性顺序` 标注 |
| @Exclude | 排除字段,不进行序列化和反序列化 |
| @Morph | Set、List、Map 等集合添加 |
##2. 分布式限流
### 2.1 开启限流组件
```yaml
mica:
redis:
rate-limiter:
enable: true
```
### 2.2 使用注解
```java
@RateLimiter
```
### 2.3 使用 Client
```java
@Autowired
private RateLimiterClient rateLimiterClient;
```
......@@ -82,7 +82,6 @@ public interface RateLimiterClient {
throw Exceptions.unchecked(e);
}
}
long seconds = timeUnit.toSeconds(ttl);
throw new RateLimiterException("您的访问次数已超限:" + key + ",速率:" + max + "/" + seconds + "s");
throw new RateLimiterException(key, max, ttl, timeUnit);
}
}
......@@ -16,14 +16,27 @@
package net.dreamlu.mica.redis.ratelimiter;
import lombok.Getter;
import java.util.concurrent.TimeUnit;
/**
* 限流异常
*
* @author L.cm
*/
@Getter
public class RateLimiterException extends RuntimeException {
private final String key;
private final long max;
private final long ttl;
private final TimeUnit timeUnit;
public RateLimiterException(String message) {
super(message);
public RateLimiterException(String key, long max, long ttl, TimeUnit timeUnit) {
super(String.format("您的访问次数已超限:%s,速率:%d/%ds", key, max, timeUnit.toSeconds(ttl)));
this.key = key;
this.max = max;
this.ttl = ttl;
this.timeUnit = timeUnit;
}
}
......@@ -62,8 +62,10 @@ public class RedisRateLimiterClient implements RateLimiterClient {
List<String> keys = Collections.singletonList(redisKeyBuilder);
// 毫秒,考虑主从策略和脚本回放机制,这个time由客户端获取传入
long now = System.currentTimeMillis();
// 转为毫秒,pexpire
long ttlMillis = timeUnit.toMillis(ttl);
// 执行命令
List<Long> results = this.redisTemplate.execute(this.script, keys, max + "", ttl + "", now + "");
List<Long> results = this.redisTemplate.execute(this.script, keys, max + "", ttlMillis + "", now + "");
// 结果为空返回失败
if (results == null || results.isEmpty()) {
return false;
......
......@@ -23,6 +23,6 @@ else
-- 没有达到阈值 value + 1
redis.call("zadd", key, now, now)
-- 秒为单位设置 key 的生存时间
redis.call("expire", key, ttl)
redis.call("pexpire", key, ttl)
return nextLimit
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册