Skip to content

Commit

Permalink
feat: 添加注释#1539
Browse files Browse the repository at this point in the history
  • Loading branch information
zacYL committed Apr 17, 2024
1 parent 65cafee commit d487394
Show file tree
Hide file tree
Showing 41 changed files with 267 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,15 @@ class RateLimiterAutoConfiguration {
): WebMvcConfigurer {
return object : WebMvcConfigurer {
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(RateLimitHandlerInterceptor(
rateLimiterProperties = rateLimiterProperties,
urlRateLimiterService = urlRateLimiterService,
usageRateLimiterService = usageRateLimiterService,
userUrlRateLimiterService = userUrlRateLimiterService,
userUsageRateLimiterService = userUsageRateLimiterService,
))
registry.addInterceptor(
RateLimitHandlerInterceptor(
rateLimiterProperties = rateLimiterProperties,
urlRateLimiterService = urlRateLimiterService,
usageRateLimiterService = usageRateLimiterService,
userUrlRateLimiterService = userUrlRateLimiterService,
userUsageRateLimiterService = userUsageRateLimiterService,
)
)
.excludePathPatterns("/service/**", "/replica/**")
.order(Ordered.LOWEST_PRECEDENCE)
super.addInterceptors(registry)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ import org.springframework.data.redis.core.script.DefaultRedisScript
import java.util.concurrent.TimeUnit
import kotlin.system.measureTimeMillis

/**
* 分布式固定时间窗口算法实现
*/
class DistributedFixedWindowRateLimiter(
private val key: String,
private val limit: Long,
private val limitUnit: TimeUnit,
private val redisTemplate: RedisTemplate<String, String>,
): RateLimiter {
) : RateLimiter {
override fun tryAcquire(permits: Long): Boolean {
try {
var acquireResult = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,20 @@ import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.core.script.DefaultRedisScript
import kotlin.system.measureTimeMillis


/**
* 分布式令牌桶算法实现
*/
class DistributedTokenBucketRateLimiter(
private val key: String,
private val permitsPerSecond: Double,
private val capacity: Long,
private val redisTemplate: RedisTemplate<String, String>,
): RateLimiter {
) : RateLimiter {
override fun tryAcquire(permits: Long): Boolean {

try {

var acquireResult: Boolean = false
var acquireResult = false
val elapsedTime = measureTimeMillis {
val redisScript = DefaultRedisScript(LuaScript.tokenBucketRateLimiterScript, List::class.java)
val results = redisTemplate.execute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock

/**
* 单机固定窗口算法实现
*/
class FixedWindowRateLimiter(
private val limit: Long,
private val unit: TimeUnit,
private val stopWatch: Stopwatch = Stopwatch.createStarted()
): RateLimiter {
) : RateLimiter {

private val currentValue: AtomicLong = AtomicLong(0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ import com.tencent.bkrepo.common.ratelimiter.constant.TRY_LOCK_TIMEOUT
import com.tencent.bkrepo.common.ratelimiter.exception.AcquireLockFailedException
import java.util.concurrent.TimeUnit

/**
* 单机令牌桶算法实现
*/
class TokenBucketRateLimiter(
private val permitsPerSecond: Long,
): RateLimiter {
) : RateLimiter {

private val guavaRateLimiter = com.google.common.util.concurrent.RateLimiter.create(permitsPerSecond.toDouble())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties
@ConfigurationProperties(prefix = "rate.limiter")
data class RateLimiterProperties(
var enabled: Boolean = false,
// 生效范围
var scope: WorkScope = WorkScope.LOCAL,
var dryRun: Boolean = false,
// 配置规则刷新频率 单位为秒
var refreshDuration: Long = 10L,
// 本地缓存限流算法实现的最大个数
var cacheCapacity: Long = 1024L,
// 限流配置
var rules: List<ResourceLimit> = mutableListOf(),
// 等待时间,单位毫秒
var sleepTime: Long = 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ package com.tencent.bkrepo.common.ratelimiter.exception
import com.tencent.bkrepo.common.api.exception.ErrorCodeException
import com.tencent.bkrepo.common.api.message.CommonMessageCode

/**
* 获取对应执行计划失败
*/
data class AcquireLockFailedException(
val reason: String
): ErrorCodeException(CommonMessageCode.ACQUIRE_LOCK_FAILED, reason)
) : ErrorCodeException(CommonMessageCode.ACQUIRE_LOCK_FAILED, reason)

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ package com.tencent.bkrepo.common.ratelimiter.exception
import com.tencent.bkrepo.common.api.exception.ErrorCodeException
import com.tencent.bkrepo.common.api.message.CommonMessageCode

/**
* 资源无效异常
*/
data class InvalidResourceException(
val reason: String
): ErrorCodeException(CommonMessageCode.INVALID_CONFIG, reason)
) : ErrorCodeException(CommonMessageCode.INVALID_CONFIG, reason)

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import com.tencent.bkrepo.common.api.constant.HttpStatus
import com.tencent.bkrepo.common.api.exception.ErrorCodeException
import com.tencent.bkrepo.common.api.message.CommonMessageCode

/**
* 超过限流配置异常
*/
data class OverloadException(
val resource: String
): ErrorCodeException(CommonMessageCode.RATE_LIMITER_OVERLOAD, resource, status = HttpStatus.TOO_MANY_REQUESTS)
) : ErrorCodeException(CommonMessageCode.RATE_LIMITER_OVERLOAD, resource, status = HttpStatus.TOO_MANY_REQUESTS)
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ import com.tencent.bkrepo.common.ratelimiter.metrics.RateLimiterMetrics
import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit
import java.time.Duration

/**
* 限流相关指标采集拦截器
*/
class MonitorRateLimiterInterceptorAdaptor(
private val rateLimiterMetrics: RateLimiterMetrics
): RateLimiterInterceptorAdapter() {
) : RateLimiterInterceptorAdapter() {

private val startTime: ThreadLocal<Long> = ThreadLocal()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ import org.springframework.web.servlet.HandlerInterceptor
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
* 针对http请求添加限流拦截
*/
class RateLimitHandlerInterceptor(
private val rateLimiterProperties: RateLimiterProperties,
private val urlRateLimiterService: UrlRateLimiterService,
private val usageRateLimiterService: UsageRateLimiterService,
private val userUrlRateLimiterService: UserUrlRateLimiterService,
private val userUsageRateLimiterService: UserUsageRateLimiterService
): HandlerInterceptor {
) : HandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
return try {
if (rateLimiterProperties.enabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ package com.tencent.bkrepo.common.ratelimiter.interceptor

import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit

/**
* 限流执行拦截器
*/
interface RateLimiterInterceptor {

/**
* 限流判断前处理
*/
fun beforeLimitCheck(resource: String)

/**
* 限流判断后处理
*/
fun afterLimitCheck(
resource: String, resourceLimit: ResourceLimit?,
result: Boolean, e: Exception?, applyPermits: Long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ package com.tencent.bkrepo.common.ratelimiter.interceptor

import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit

abstract class RateLimiterInterceptorAdapter: RateLimiterInterceptor {
/**
* 限流算法执行前后校验拦截器
*/
abstract class RateLimiterInterceptorAdapter : RateLimiterInterceptor {
override fun beforeLimitCheck(resource: String) = Unit

override fun afterLimitCheck(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ package com.tencent.bkrepo.common.ratelimiter.interceptor

import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit

/**
* 限流拦截器链
*/
class RateLimiterInterceptorChain(
private val interceptors: MutableList<RateLimiterInterceptor> = mutableListOf()
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

package com.tencent.bkrepo.common.ratelimiter.metrics

/**
* 指标类型
*/
enum class MetricType {
TOTAL, // 总请求数量
PASSED, // 通过数量
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Timer
import java.time.Duration

/**
* 限流指标写入
*/
class RateLimiterMetrics(private val registry: MeterRegistry) {

fun collectMetrics(
Expand All @@ -61,7 +64,8 @@ class RateLimiterMetrics(private val registry: MeterRegistry) {
getExceptionCounter(resource).increment(applyPermits.toDouble())
}
getLimitCheckDuration(resource).record(duration)
} catch (ignore: Exception) {}
} catch (ignore: Exception) {
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import org.springframework.util.StreamUtils
import java.io.IOException
import java.nio.charset.StandardCharsets

/**
* lua脚本加载
*/
object LuaScript {
private val logger = LoggerFactory.getLogger(LuaScript::class.java)
private const val FIX_WINDOW_RATE_LIMITER_FILE_PATH = "META-INF/fix-window-rate-limiter.lua"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,26 @@

package com.tencent.bkrepo.common.ratelimiter.rule

/**
* 限流配置规则处理
*/
interface RateLimitRule {

/**
* 获取资源对应的规则
* 优先查找resource, 如查不到对应规则,则通过extraResource查找
* resource一般是特定类型,如特定用户,特定URL,特定项目仓库等
* extraResource一般是某一类类型,如所有用户、URL模版、所有仓库等
*/
fun getRateLimitRule(resource: String, extraResource: List<String> = emptyList()): ResourceLimit?

/**
* 添加限流规则
*/
fun addRateLimitRule(resourceLimit: ResourceLimit)

/**
* 批量添加限流规则
*/
fun addRateLimitRules(resourceLimit: List<ResourceLimit>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@ import com.tencent.bkrepo.common.ratelimiter.enums.Algorithms
import com.tencent.bkrepo.common.ratelimiter.enums.LimitDimension
import java.util.concurrent.TimeUnit

/**
* 限流规则
*/
data class ResourceLimit(
// 算法选择
var algo: Algorithms = Algorithms.FIXED_WINDOW,
// 资源标识
var resource: String = "/",
// 限流维度
var limitDimension: LimitDimension = LimitDimension.URL,
// 限流值
var limit: Long = -1,
// 桶容量(令牌桶使用)
var bucketCapacity: Long? = null,
// 限流时间单位
var unit: TimeUnit = TimeUnit.SECONDS,
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ import com.tencent.bkrepo.common.ratelimiter.rule.RateLimitRule
import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit
import java.util.concurrent.ConcurrentHashMap

open class BandwidthRateLimitRule: RateLimitRule {
/**
* 带宽限流配置规则实现
*/
open class BandwidthRateLimitRule : RateLimitRule {

val bandwidthLimitRules: ConcurrentHashMap<String, ResourceLimit> = ConcurrentHashMap()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ package com.tencent.bkrepo.common.ratelimiter.rule.url
import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit
import java.util.concurrent.ConcurrentHashMap

/**
* url 节点
*/
class UrlNode(
val pathDir: String,
val isPattern: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ import com.tencent.bkrepo.common.ratelimiter.enums.LimitDimension
import com.tencent.bkrepo.common.ratelimiter.rule.RateLimitRule
import com.tencent.bkrepo.common.ratelimiter.rule.ResourceLimit

class UrlRateLimitRule: RateLimitRule {
/**
* URL限流配置规则实现
*/
class UrlRateLimitRule : RateLimitRule {

// 指定URL规则
private val urlLimitRules: UrlResourceLimitRule = UrlResourceLimitRule()
// 某一类url对应规则
private val urlTemplateLimitRules: UrlResourceLimitRule = UrlResourceLimitRule()

override fun getRateLimitRule(resource: String, extraResource: List<String>): ResourceLimit? {
Expand Down
Loading

0 comments on commit d487394

Please sign in to comment.