| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package com.pharmacopoeia.service;
- import com.pharmacopoeia.config.DashScopeRateLimitProperties;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Service;
- import java.time.LocalDate;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * 百炼 API 全局调用限流器(内存计数,重启清零)。
- * 控制后端 → 百炼的总调用量,与用户侧限流独立。
- */
- @Service
- public class DashScopeRateLimiter {
- private static final Logger log = LoggerFactory.getLogger(DashScopeRateLimiter.class);
- private final DashScopeRateLimitProperties props;
- private final AtomicInteger minuteCount = new AtomicInteger(0);
- private final AtomicInteger hourCount = new AtomicInteger(0);
- private final AtomicInteger dayCount = new AtomicInteger(0);
- private volatile String currentDate = LocalDate.now().toString();
- private volatile int currentHour = java.time.LocalTime.now().getHour();
- public DashScopeRateLimiter(DashScopeRateLimitProperties props) {
- this.props = props;
- }
- /** 尝试获取一次调用许可。返回 true 表示放行,false 表示超限。 */
- public boolean tryAcquire() {
- if (!props.isEnabled()) return true;
- resetIfNeeded();
- if (props.getPerMinute() > 0 && minuteCount.incrementAndGet() > props.getPerMinute()) {
- log.warn("百炼 API 每分钟限流触发: {}/{}", minuteCount.get(), props.getPerMinute());
- return false;
- }
- if (props.getPerHour() > 0 && hourCount.incrementAndGet() > props.getPerHour()) {
- log.warn("百炼 API 每小时限流触发: {}/{}", hourCount.get(), props.getPerHour());
- return false;
- }
- if (props.getPerDay() > 0 && dayCount.incrementAndGet() > props.getPerDay()) {
- log.warn("百炼 API 每日限流触发: {}/{}", dayCount.get(), props.getPerDay());
- return false;
- }
- return true;
- }
- private void resetIfNeeded() {
- String today = LocalDate.now().toString();
- int nowHour = java.time.LocalTime.now().getHour();
- if (!currentDate.equals(today)) {
- dayCount.set(0);
- currentDate = today;
- }
- if (currentHour != nowHour) {
- hourCount.set(0);
- currentHour = nowHour;
- }
- }
- }
|