You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为bucket4j-spring-boot-starter开启详细DEBUG日志并排查问题?

问题:Spring Boot 2.7.18集成Bucket4J限流跨环境失效+日志无法输出

我在MVC应用中使用Spring Boot 2.7.18结合bucket4j-spring-boot-starter,仅通过properties文件配置实现接口限流。本地环境限流功能正常,但其他部署环境完全不生效。我尝试开启Bucket4J的详细DEBUG日志排查问题,但配置后无论本地还是部署环境都无日志输出,怀疑需要配置切面处理日志但找不到合适示例。

一、当前日志配置(application.properties)

logging.file.name=c:/temp/myapp.log
logging.level.root=INFO
logging.level.org.hibernate.SQL=INFO
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=INFO

# 以下配置无任何输出
logging.level.com.giffing.bucket4j.spring.boot.starter=DEBUG
logging.level.io.github.bucket4j=TRACE

二、限流相关依赖(pom.xml)

<dependency> 
    <groupId>com.giffing.bucket4j.spring.boot.starter</groupId>
    <artifactId>bucket4j-spring-boot-starter</artifactId>
    <version>0.8.1</version> <!-- 无法升级,因为高版本依赖Spring Boot 3 -->
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>3.1.8</version>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>jcache</artifactId>
    <version>3.1.8</version>
</dependency>      
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

三、Bucket4J限流配置(application.properties)

spring.cache.cache-names=rate-limit-bucket
spring.cache.jcache.provider=com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
spring.cache.caffeine.spec=maximumSize=1000000,expireAfterAccess=3600s

bucket4j.enabled=true
bucket4j.filters[0].cache-name=rate-limit-bucket
bucket4j.filters[0].cache-key=getRemoteAddr()
bucket4j.filters[0].url=^.*/(download?|cancel|someaction).*$
bucket4j.filters[0].http-response-body="{ \"status\": 429, \"error\": \"Too Many Requests\", \"message\": \"You have exhausted your API Request Quota\" }"
bucket4j.filters[0].rate-limits[0].bandwidths[0].capacity=1
bucket4j.filters[0].rate-limits[0].bandwidths[0].time=5
bucket4j.filters[0].rate-limits[0].bandwidths[0].unit=seconds

解决思路

一、先解决日志无法输出的问题

  • 检查配置优先级:部署环境如果使用了外部配置源(如配置中心、环境变量),可能覆盖了本地properties中的日志级别配置,务必确认部署环境的logging.level.com.giffing.bucket4j.spring.boot.starter和logging.level.io.github.bucket4j确实设置为DEBUG/TRACE。
  • 排查日志框架自定义配置:Spring Boot 2.7.x默认用Logback,检查项目中是否有logback.xml或logback-spring.xml,里面可能对这些包的日志级别做了强制限制(比如设为INFO),覆盖了properties的配置。
  • 手动添加AOP切面打印日志:如果上述方法无效,直接通过Spring AOP拦截Bucket4J的核心过滤器,手动输出日志:
    1. 先引入AOP依赖:
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
      </dependency>
      
    2. 编写切面类:
      @Aspect
      @Component
      public class Bucket4jLoggingAspect {
          private static final Logger log = LoggerFactory.getLogger(Bucket4jLoggingAspect.class);
      
          @Around("execution(* com.giffing.bucket4j.spring.boot.starter.filter.servlet.Bucket4JFilter.doFilter(..))")
          public Object logBucket4jFilter(ProceedingJoinPoint joinPoint) throws Throwable {
              HttpServletRequest request = (HttpServletRequest) joinPoint.getArgs()[0];
              String uri = request.getRequestURI();
              String clientIp = request.getRemoteAddr();
              log.debug("Bucket4J处理请求:URI={}, 客户端IP={}", uri, clientIp);
              try {
                  Object result = joinPoint.proceed();
                  log.debug("Bucket4J允许请求:URI={}", uri);
                  return result;
              } catch (Exception e) {
                  if (e.getCause() instanceof BucketExecutionException) {
                      log.debug("Bucket4J拒绝请求:URI={}, 原因:请求超出限流配额", uri);
                  }
                  throw e;
              }
          }
      }
      

二、排查跨环境限流失效的问题

  • 验证缓存初始化状态:部署环境中Caffeine缓存可能未正确加载,添加代码打印已初始化的缓存列表:
    @Autowired
    private CacheManager cacheManager;
    
    @PostConstruct
    public void checkCacheStatus() {
        log.info("当前已加载缓存:{}", cacheManager.getCacheNames());
    }
    
    确认rate-limit-bucket缓存存在。
  • 修正客户端IP获取逻辑:部署环境如果有反向代理/负载均衡,getRemoteAddr()拿到的是代理服务器IP,导致所有请求共用同一个Bucket,限流失效。修改cache-key为真实客户端IP的请求头,比如:
    bucket4j.filters[0].cache-key=getHeader('X-Forwarded-For') != null ? getHeader('X-Forwarded-For').split(',')[0].trim() : getRemoteAddr()
    
    同时确保反向代理服务器正确传递X-Forwarded-For或X-Real-IP头。
  • 检查URL匹配规则:部署环境的请求可能带有上下文路径,导致配置的^.*/(download?|cancel|someaction).*$不匹配。可以在日志中打印完整请求URI,调整正则表达式适配实际URL结构。
  • 调整过滤器执行顺序:如果Bucket4J过滤器在其他过滤器(如认证、编码过滤器)之后执行,可能还没到限流判断就被拦截。通过配置调整顺序:
    bucket4j.filters[0].order=1
    
    让它优先执行。

内容的提问来源于stack exchange,提问作者hello_earth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:14:52