【MS】网关 springcloud-gateway 多维度可配置自定义限流参数
自定义限流参数在《【MS】springcloud-gateway 基于Token限流》那篇文章中,最后自己定义的redis限流实现中的限流参数哪里来的?这就是定义的redis限流实现的原因,因为gateway官方提供的是两个参数配置死在yml中,所以我们想要根据不同的用户来限制,只能自己重写限流实现。本篇文章介绍自定义限流维度:1、数据库表设计CREATE TABLE `sys_rate...
·
自定义限流参数
因为gateway官方提供的是两个参数配置死在yml中,所以我们想要根据不同的用户来限制,只能自己重写限流实现。
本篇文章介绍自定义限流维度:
1、数据库表设计
CREATE TABLE `sys_rate_limiter` (
`limit_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`level` varchar(255) NOT NULL COMMENT '等级',
`replenish_rate` int(11) NOT NULL COMMENT '流速',
`burst_capacity` int(11) NOT NULL COMMENT '桶容量',
`limit_type` int(10) NOT NULL COMMENT '单位 1:秒,2:分钟,3:小时,4:天',
PRIMARY KEY (`limit_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
对于该表curd不再重述
具体代码在 ms-common
> ms-common-gateway
中
2、定义接口标准
public interface LimiterLevelResolver {
default void save(RateLimiterLevel limiterLevel){}
default RateLimiterLevel get(){
return null;
}
}
一个获取,一个保存方法,具体实现
public class RedisLimiterLevelHandler implements LimiterLevelResolver {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedisTokenStoreSerializationStrategy redisTokenStoreSerializationStrategy;
@Override
public void save(RateLimiterLevel limiterLevel) {
byte[] key = redisTokenStoreSerializationStrategy.serialize(CommonConstants.REDIS_LIMIT_KEY);
byte[] value = redisTokenStoreSerializationStrategy.serialize(limiterLevel);
try{
redisTemplate.getConnectionFactory().getConnection().openPipeline();
redisTemplate.getConnectionFactory().getConnection().set(key, value);
redisTemplate.getConnectionFactory().getConnection().closePipeline();
}finally {
redisTemplate.getConnectionFactory().getConnection().close();
}
}
@Override
public RateLimiterLevel get() {
byte[] key = redisTokenStoreSerializationStrategy.serialize(CommonConstants.REDIS_LIMIT_KEY);
byte[] value = redisTemplate.getConnectionFactory().getConnection().get(key);
RateLimiterLevel rateLimiterLevel = redisTokenStoreSerializationStrategy.deserialize(value,RateLimiterLevel.class);
if(ObjectUtil.isNull(value) || ObjectUtil.isNull(rateLimiterLevel) || CollUtil.isEmpty(rateLimiterLevel.getLevels())){
rateLimiterLevel = new RateLimiterLevel();
List<RateLimiterVO> vos = new ArrayList<>();
vos.add(RateLimiterVO
.builder()
.level(CommonConstants.DEFAULT_LEVEL)
.burstCapacity(CommonConstants.DEFAULT_LIMIT_LEVEL)
.replenishRate(CommonConstants.DEFAULT_LIMIT_LEVEL)
.limitType(CommonConstants.DEFAULT_LIMIT_TYPE)
.build());
rateLimiterLevel.setLevels(vos);
}
return rateLimiterLevel;
}
}
3、加载数据库配置的限流参数
在服务启动的时候自动把数据库的中的限流参数,通过调用 LimiterLevelResolver
接口中的save方法保存到redis中
具体实现 在 ms-admin
服务中
@Slf4j
@Configuration
@AllArgsConstructor
public class LimiterInitConfig {
private final SysRateLimitService sysRateLimitService;
private final LimiterLevelResolver limiterLevelResolver;
@Async
@Order
@EventListener({WebServerInitializedEvent.class})
public void initLimit(){
List<SysRateLimiter> list = sysRateLimitService.list();
RateLimiterLevel rateLimiterLevel = new RateLimiterLevel();
Map<String,Integer[]> map = new HashMap<>();
list.forEach(sysRateLimiter -> {
map.put(sysRateLimiter.getLevel(),new Integer[]{sysRateLimiter.getReplenishRate(),sysRateLimiter.getBurstCapacity(),sysRateLimiter.getLimitType()});
});
rateLimiterLevel.setLevels(map);
limiterLevelResolver.save(rateLimiterLevel);
log.info("==============限流配置初始化成功================");
}
}
本篇介绍了,把限流参数放到redis,下一篇介绍,在http请求过来的时候,经过网关,在网关中使用保存在redis中的限流参数进行限流《网关 springcloud-gateway 基于Token限流》
具体代码:传送门 : https://github.com/yzcheng90/ms
更多推荐
已为社区贡献2条内容
所有评论(0)