package com.malk.apigw.caller; import com.google.common.util.concurrent.RateLimiter; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 按 callerId 本地限流(capability: baas-gateway / REQ-GW-005) * *

单 JVM 内存级。Guava RateLimiter per callerId,LRU 无需(caller 数量有限)。

*/ @Component public class CallerRateLimiter { private final Map limiters = new ConcurrentHashMap<>(); /** * 尝试获取一个许可;不阻塞。 * * @param callerId 调用方 ID * @param qps 限流阈值(从 CallerProfile.rateLimit) * @return true=通过,false=被限流 */ public boolean tryAcquire(String callerId, int qps) { if (qps <= 0) return true; RateLimiter rl = limiters.computeIfAbsent(callerId, id -> RateLimiter.create(qps)); // rate 变更时重建 if (Math.abs(rl.getRate() - qps) > 0.001) { rl = RateLimiter.create(qps); limiters.put(callerId, rl); } return rl.tryAcquire(); } }