package com.ypp.ratelimit.starter.chain.impl;
import cn.hutool.core.util.ObjectUtil;
import com.ypp.ratelimit.starter.RateLimitProperties;
import com.ypp.ratelimit.starter.blacklist.BlackListRecordHandler;
import com.ypp.ratelimit.starter.chain.RateLimitHandlerChain;
import com.ypp.ratelimit.starter.constant.LimitPrefixKey;
import com.ypp.ratelimit.starter.limiter.BaseRateLimitProperties;
import com.ypp.ratelimit.starter.limiter.counter.CounterRateLimitProperties;
import com.ypp.ratelimit.starter.limiter.counter.CounterRateLimiter;
import com.ypp.ratelimit.starter.limiter.slidingwindow.SlidingWindowRateLimitProperties;
import com.ypp.ratelimit.starter.limiter.slidingwindow.SlidingWindowRateLimiter;
import com.ypp.ratelimit.starter.limiter.tokenbucket.TokenBucketRateLimitProperties;
import com.ypp.ratelimit.starter.limiter.tokenbucket.TokenBucketRateLimiter;
import com.ypp.util.string.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author ypp
* @date 2022-06-23 14:00
**/
@Slf4j
@Component
@Scope("prototype")
public class DefaultRateLimitHandlerChain implements RateLimitHandlerChain, InitializingBean {
private List<BaseRateLimitProperties> rateLimitPropertiesList;
@Autowired
private CounterRateLimiter counterRateLimiter;
@Autowired
private SlidingWindowRateLimiter slidingWindowRateLimiter;
@Autowired
private TokenBucketRateLimiter tokenBucketRateLimiter;
@Autowired
private RateLimitProperties rateLimitProperties;
@Autowired
private BlackListRecordHandler blackListRecordHandler;
@Override
public void afterPropertiesSet() throws Exception {
rateLimitPropertiesList = new ArrayList<>();
}
@Override
public RateLimitHandlerChain add(BaseRateLimitProperties rateLimitProperties) {
rateLimitPropertiesList.add(rateLimitProperties);
return this;
}
@Override
public RateLimitHandlerChain addAll(List<BaseRateLimitProperties> rateLimitPropertiesList) {
this.rateLimitPropertiesList.addAll(rateLimitPropertiesList);
return this;
}
@Override
public boolean handle() {
if (CollectionUtils.isEmpty(rateLimitPropertiesList)) {
return true;
}
boolean acquire = false;
for (BaseRateLimitProperties rateLimitProperties : rateLimitPropertiesList) {
if (rateLimitProperties instanceof CounterRateLimitProperties) {
acquire = handle((CounterRateLimitProperties) rateLimitProperties);
} else if (rateLimitProperties instanceof SlidingWindowRateLimitProperties) {
acquire = handle((SlidingWindowRateLimitProperties) rateLimitProperties);
} else if (rateLimitProperties instanceof TokenBucketRateLimitProperties) {
acquire = handle((TokenBucketRateLimitProperties) rateLimitProperties);
}
if (!acquire) {
return false;
}
}
return true;
}
private boolean handle(CounterRateLimitProperties counterRateLimitProperties) {
boolean acquire = counterRateLimiter.tryAcquire(counterRateLimitProperties.getKey(),
counterRateLimitProperties.getCount(),
counterRateLimitProperties.getTime(),
TimeUnit.valueOf(counterRateLimitProperties.getTimeUnit()));
logLimit(acquire, counterRateLimitProperties.getPrefixKey(), counterRateLimitProperties.getKey());
return acquire;
}
private boolean handle(SlidingWindowRateLimitProperties slidingWindowRateLimitProperties) {
boolean acquire = slidingWindowRateLimiter.tryAcquire(slidingWindowRateLimitProperties.getKey(),
slidingWindowRateLimitProperties.getCount(),
slidingWindowRateLimitProperties.getTime(),
TimeUnit.valueOf(slidingWindowRateLimitProperties.getTimeUnit()));
logLimit(acquire, slidingWindowRateLimitProperties.getPrefixKey(), slidingWindowRateLimitProperties.getKey());
return acquire;
}
private boolean handle(TokenBucketRateLimitProperties tokenBucketRateLimitProperties) {
boolean acquire = tokenBucketRateLimiter.tryAcquire(tokenBucketRateLimitProperties.getKey(),
tokenBucketRateLimitProperties.getRate(),
tokenBucketRateLimitProperties.getCapacity());
logLimit(acquire, tokenBucketRateLimitProperties.getPrefixKey(), tokenBucketRateLimitProperties.getKey());
return acquire;
}
private void logLimit(boolean acquire, String prefixKey, String key) {
if (!acquire) {
if (ObjectUtil.equals(prefixKey, LimitPrefixKey.IP.getPrefixKey())) {
log.debug("IP限流:{}", key);
// IP限流
if (rateLimitProperties.getRecordIpLimit()) {
blackListRecordHandler.record(LimitPrefixKey.IP, key.substring(0, key.indexOf(StringUtils.SPE2)));
}
} else if (ObjectUtil.equals(prefixKey, LimitPrefixKey.USER_ID.getPrefixKey())) {
log.debug("用户限流:{}", key);
// 用户限流
if (rateLimitProperties.getRecordUserIdLimit()) {
blackListRecordHandler.record(LimitPrefixKey.USER_ID, key.substring(0, key.indexOf(StringUtils.SPE2)));
}
} else if (ObjectUtil.equals(prefixKey, LimitPrefixKey.TOTAL.getPrefixKey())) {
log.debug("总限流:{}", key);
}
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
基于redis实现的限流SpringBootStarter.zip
共32个文件
java:27个
lua:3个
xml:1个
需积分: 5 0 下载量 13 浏览量
2023-04-23
17:38:34
上传
评论
收藏 26KB ZIP 举报
温馨提示
基于redis实现限流方法,支持三种算法:简单计数、滑动窗口、令牌桶 自动注入CounterRateLimiter、TokenBucketRateLimiter、SlidingWindowRateLimiter (1)CounterRateLimiter(简单计数限流): 限制在一定时间time内,调用次数不能超过count,超过后,在后续time时间内都会被限流 (2)TokenBucketRateLimiter(令牌桶限流): 固定速率(rate/s)往桶中放令牌,桶的容量为capacity,当1s内有capacity个请求达到,那么可以应对(突发的流量), 但后续桶中没有令牌可用时,则被限流。 (3)SlidingWindowRateLimiter(滑动窗口限流): 将限流时间窗口内的请求会被计算到限流次数中,且窗口是跟随时间滑动的,配置参数同CounterRateLimiter
资源推荐
资源详情
资源评论
收起资源包目录
基于redis实现的限流SpringBootStarter.zip (32个子文件)
pom.xml 1KB
src
main
resources
sliding_window_rate_limit.lua 328B
counter_rate_limit.lua 496B
token_bucket_rate_limit.lua 2KB
META-INF
spring.factories 120B
java
com
ypp
ratelimit
starter
constant
LimitScope.java 504B
RateLimitAlgorithm.java 631B
LimitPrefixKey.java 592B
RateLimitRedisKeyConstants.java 447B
LimitMethod.java 345B
blacklist
BlackListRecordHandler.java 410B
impl
BlackListRecordRedisHandler.java 1KB
RedisRateLimitAutoConfiguration.java 4KB
annotation
RateLimitKey.java 431B
RateLimit.java 2KB
RateLimits.java 335B
limiter
counter
CounterRateLimiter.java 538B
RedisCounterRateLimiter.java 1KB
CounterRateLimitProperties.java 753B
slidingwindow
RedisSlidingWindowRateLimiter.java 2KB
SlidingWindowRateLimiter.java 550B
SlidingWindowRateLimitProperties.java 784B
tokenbucket
TokenBucketRateLimiter.java 447B
TokenBucketRateLimitProperties.java 622B
RedisTokenBucketRateLimiter.java 1KB
RateLimitHandlerProperties.java 789B
BaseRateLimitProperties.java 721B
RateLimitProperties.java 853B
util
ObjectMapperSupport.java 6KB
LimitErrorMsgUtils.java 560B
chain
RateLimitHandlerChain.java 798B
impl
DefaultRateLimitHandlerChain.java 6KB
共 32 条
- 1
资源评论
来了就走下去
- 粉丝: 111
- 资源: 19
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab开发的根据rvm回归模型自己编的matlab程序.rar
- 高效C++学生成绩管理系统:教育技术+C++17编程+数据管理+教务自动化
- 基于matlab开发的Tipping的相关向量机RVM的回归MATLAB程序,有英文注释,可以运行.rar
- 一个点击正反转程序实例,可实现案件电机正反转
- 搜索链接淘特搜索引擎共享版-tot-search-engine.rar
- 第十八届全国大学生智能汽车竞赛 摄像头组/镜头组
- 基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar
- 基于SSM的“个性化电子相册”的设计与实现.zip
- 如何在撰写科研文献时,使用ai工具辅助去完成科研工作
- 吉林大学计组笔记 自用 基于b站翼云图灵的课.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功