apolloconfig / apollo

Apollo is a reliable configuration management system suitable for microservice configuration management scenarios.
https://www.apolloconfig.com
Apache License 2.0
29.17k stars 10.2k forks source link

Apollo OpenAPI在apollo-portal中缺失限流功能,是否可以补充限流功能 #5244

Open youngzil opened 1 month ago

youngzil commented 1 month ago

你的特性请求和某个问题有关吗?请描述

目前的Apollo OpenAPI缺失必要的限流功能,很容易出现业务端的滥用或者误用,导致请求量过大的情况,影响apollo-portal的稳定性
在 apollo-portal中的 ConsumerAuthenticationFilter 是否可以新增限流功能

清晰简洁地描述一下你希望的解决方案

在 apollo-portal中的 ConsumerAuthenticationFilter 是否可以新增限流功能 初步方案:

  1. consumertoken表中新增LimitCount字段,保存每个Token的限流值
  2. 在 apollo-portal中的 ConsumerAuthenticationFilter 处理获取每个Token的限流值,并进行限流逻辑处理

清晰简洁地描述一下这个特性的备选方案

其它背景

BTW:如果觉得这个特性合理,我可以细化实现方案 并实现

nobodyiam commented 1 month ago

Sounds a good idea.

youngzil commented 2 weeks ago

此方案是基于单机限流方案,且所有限流数据均保存在本地缓存

元数据设计:

  1. consumertoken表中新增LimitCount字段,保存每个Token的限流值
  2. 在PortalConfig中新增 open.api.limit.count 设置默认限流值,当创建新的Token时,用来设置LimitCount字段值
  3. PortalConfig中新增 open.api.limit.enabled ,默认为false,需要手动开启
  4. PortalConfig中新增 open.api.limit.white,配置哪些token可以不进行限流

实现逻辑:

  1. 在 apollo-portal中的 ConsumerAuthenticationFilter 中使用Guava LoadingCache保存限流器RateLimiter,key为token
  2. 对每个请求的Token进行限流判断
  3. 自定义限流器接口,默认实现为 Guava RateLimiter,用户可以自行实现其他的限流策略、集群限流等

RateLimiter接口设计 public interface RateLimiter { boolean tryAcquire(); boolean tryAcquire(int permits) boolean tryAcquire(int permits, long timeout, TimeUnit unit) void setRate(double permitsPerSecond); double getRate(); void destroy() }

BTW: 实际使用经验中,Guava RateLimiter在初始化时存在第一秒的误限,通过新增默认1S的WARMUP时间不限流来解决,是否有必要增加WARMUP逻辑,或者其他更好的实现方案

nobodyiam commented 2 weeks ago

open.api.limit.white

不太建议设置白名单直接跳过,可以通过配置较大的限流值?

youngzil commented 2 weeks ago

不太建议设置白名单直接跳过,可以通过配置较大的限流值?

可以去除白名单设置,可以通过增加一些逻辑来解决,当token的LimitCount发生变化时,需要立刻销毁 old RateLimiter,重建该Token的RateLimiter来实时生效