Spring Boot中bucket4j的Redis TTL始终为-1无法配置
Bucket4j Redis缓存TTL始终为-1的排查与解决
核心原因:Spring Cache配置对Bucket4j不生效
你当前通过RedisCacheManager配置的TTL只对Spring Cache管理的缓存(比如你的other缓存)生效,但Bucket4j是直接操作Redis客户端,不会走Spring Cache的缓存管理器流程,所以给bucket4j缓存名配置的TTL完全不会被Bucket4j识别。
正确配置方式:给Bucket4j单独设置Redis过期时间
需要在Bucket4j的Redis桶配置中显式指定过期时间,而非依赖Spring Cache的配置。以下是Kotlin示例:
@Bean fun bucket4jRedisCache(redisTemplate: RedisTemplate<String, ByteArray>): Bucket4jRedisCache { val redisProxy = RedisProxyFactory.newInstance(redisTemplate.connectionFactory) // 配置Bucket4j的Redis缓存,指定TTL return Bucket4jRedisCache.builder() .expireAfterWrite(Duration.of(100, ChronoUnit.SECONDS)) .redisProxy(redisProxy) .build() } // 创建Bucket时关联配置 @Bean fun rateLimiter(bucket4jRedisCache: Bucket4jRedisCache): Bucket { val configuration = BucketConfiguration.builder() .addLimit(Bandwidth.simple(10, Duration.ofMinutes(1))) .build() return bucket4jRedisCache.builder() .key("your-bucket-key") .configuration(configuration) .build() }
序列化问题排查
如果Redis键存在序列化异常,需确保Bucket4j使用的序列化器与Spring保持一致:
- 检查
RedisTemplate的键序列化器是否为StringRedisSerializer,Bucket4j默认可能使用Jdk序列化,导致键格式异常。 - 配置Bucket4j使用String序列化:
@Bean fun bucket4jRedisCache(redisTemplate: RedisTemplate<String, ByteArray>): Bucket4jRedisCache { val redisProxy = RedisProxyFactory.newInstance(redisTemplate.connectionFactory) return Bucket4jRedisCache.builder() .expireAfterWrite(Duration.of(100, ChronoUnit.SECONDS)) .keySerializer(StringRedisSerializer()) // 指定键序列化器 .valueSerializer(JdkSerializationRedisSerializer()) // 按需配置值序列化 .redisProxy(redisProxy) .build() }
验证步骤
- 重启服务后触发Bucket4j限流逻辑,写入Redis键。
- 用Redis客户端执行
TTL your-bucket-key命令,检查返回值是否接近100。
内容的提问来源于stack exchange,提问作者Java
相关产品推荐
相关产品推荐

