CallerRateLimiter.java 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. package com.malk.apigw.caller;
  2. import com.google.common.util.concurrent.RateLimiter;
  3. import org.springframework.stereotype.Component;
  4. import java.util.Map;
  5. import java.util.concurrent.ConcurrentHashMap;
  6. /**
  7. * 按 callerId 本地限流(capability: baas-gateway / REQ-GW-005)
  8. *
  9. * <p>单 JVM 内存级。Guava RateLimiter per callerId,LRU 无需(caller 数量有限)。</p>
  10. */
  11. @Component
  12. public class CallerRateLimiter {
  13. private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
  14. /**
  15. * 尝试获取一个许可;不阻塞。
  16. *
  17. * @param callerId 调用方 ID
  18. * @param qps 限流阈值(从 CallerProfile.rateLimit)
  19. * @return true=通过,false=被限流
  20. */
  21. public boolean tryAcquire(String callerId, int qps) {
  22. if (qps <= 0) return true;
  23. RateLimiter rl = limiters.computeIfAbsent(callerId, id -> RateLimiter.create(qps));
  24. // rate 变更时重建
  25. if (Math.abs(rl.getRate() - qps) > 0.001) {
  26. rl = RateLimiter.create(qps);
  27. limiters.put(callerId, rl);
  28. }
  29. return rl.tryAcquire();
  30. }
  31. }