当前位置: 首页 > 知识库问答 >
问题:

如何使缓存数据(在redis上)在上次访问的基础上过期?

杭曦
2023-03-14

我有一个spring微服务应用程序,它使用redis服务器进行缓存存储。使用RedisCacheManager Api。在这里,我们可以选择设置“setDefaultExpiration”。因为rediscachemanager从第一次访问带注释的方法(@cacheable)开始计算过期时间。

我想从可缓存方法的最后一次访问计算到期时间,而不是从第一次访问。Google库已经给出了实现这一目标的直接方法:在CacheBuilder中,我们有一种叫做exireAfterAccess CacheBuilder API的方法

当我们想使用google gauva服务器时,我们可以使用它。但在我的应用程序中,我必须使用redis server进行缓存,因为我需要集中缓存服务器。我查看了RedisCacheManager类,但没有找到实现这一点的方法。如何在redis cache server中实现此功能。下面是创建RedisCacheManager bean的代码:

@Bean
RedisCacheManager cacheManager() {
    final RedisCacheManager redisCacheManager = new RedisCacheManager(
            redisTemplate());
    redisCacheManager.setUsePrefix(true);
    redisCacheManager.setDefaultExpiration(redisExpireTime);


    return redisCacheManager;
}

共有1个答案

米元凯
2023-03-14

我通过自定义cacheResolver解决了这个问题,但它似乎效率低下。

public class MyCacheResolver extends SimpleCacheResolver {

@Autowired
private RedisTemplate<Object, Object> template;

public CustomCacheResolver(CacheManager cacheManager) {
    super(cacheManager);
}

@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
    if (context.getOperation() instanceof CacheableOperation) {
        DefaultParameterNameDiscoverer discover = new DefaultParameterNameDiscoverer();
        CacheableOperation op = (CacheableOperation) context.getOperation();
        String[] ps = discover.getParameterNames(context.getMethod());
        EvaluationContext ctx = new StandardEvaluationContext();
        for (int i = 0; i < ps.length; i++) {
            ctx.setVariable(ps[i], context.getArgs()[i]);
        }
        ExpressionParser parser = new SpelExpressionParser();
        String redisKey = parser.parseExpression(op.getKey()).getValue(ctx, String.class);
        String prefix = getCacheNames(context).iterator().next();
        long time = template.getExpire(prefix + ":" + redisKey);
        if (time > 0) {
            template.expire(prefix + ":" + redisKey, 300L, TimeUnit.SECONDS);
        }
    }
    return super.resolveCaches(context);
}
}

在我的例子中,每次缓存命中都会自动将缓存ttl刷新到300秒。然后将cacheResolver注入配置类,

@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean("customCacheResolver")
    @Override
    public CacheResolver cacheResolver() {
        return new CustomCacheResolver(cacheManager());
    }

 @Bean
 public RedisCacheManager cacheManager() {
     //define your cacheManager here
 }

}

我希望很清楚,英语不是我的母语。

 类似资料:
  • 问题内容: 假设我有一个时间序列: 如果使用rolling_ *函数之一,例如rolling_sum,则可以得到想要的行为,用于向后看的滚动计算: 但是,如果我想做一笔前瞻性的款项怎么办?我已经尝试过这样的事情: 但这不完全是我想要的行为。我正在寻找的输出是: 即-我想要“当前”天加上接下来的两天的总和。我目前的解决方案还不够,因为我担心边缘会发生什么。我知道我可以通过设置两个分别移动1天和2天的

  • 问题内容: 在我的构建控制台顶部附近,我看到带有修订号的“上次构建修订:”。如何在我的构建脚本中访问最后构建的版本#?我正在使用Gradle,但我认为这并不重要。Jenkins是否在系统属性中提供最后构建的rev#?当然,从我的构建脚本进行访问必须很简单… 问题答案: 我不认为git插件会将上次构建的修订版导出为环境变量,但是可以使用简单的shell命令(例如: BUILD_URL始终指向构建的自

  • 问题内容: 我已经通过安装了cron 由于未运行,尝试启动cron失败(按预期方式)。 正确启动cron的命令行是什么(即它将读取用户的crontabs,将读取/ etc / crontab / *等)? 请注意,我不想将容器作为“完整”机器启动,所以我不想运行或。我通过来管理进程,所以我缺少的是添加到其配置文件的命令行。 问题答案: 您可以在没有守护程序模式的情况下运行cron。 我只是想测试一

  • 问题内容: 我已经看到了一些关于在Azure上运行Redis的人的参考,但是没有实现或任何形式的“方法”。有人看过这样的例子吗? 问题答案: 下载适用于Windows的Redis-请参阅https://github.com/ServiceStack/ServiceStack.Redis上的“ Redis Service builds for Windows”部分。我最终使用了dmajkic的win

  • 问题内容: 我读到有关Angular’$ cacheFactory’的信息,但找不到有关设置缓存内容的到期日期的任何文档。 如果我想将所有GET请求缓存30秒该怎么办,如何在’$ cacheFactory’中定义它,还是需要自己扩展功能。 问题答案: 我也面临这个问题。默认的$ cacheFactory没有生存时间(TTL)。 您将需要自己实现。但是在此之前,您可以环顾四周,看看是否有人已经这样做

  • API 3-您可以获得所有访问权限,不需要任何权限 API 4-15-您需要使用WRITE_EXTERNAL_STORAGE,您可以获得所有访问权限。 API 16-18-如果只希望读取,请使用read_external_storage API 19-20-您不能读取或写入辅助外部存储(SD卡),除非您的应用程序是系统应用程序,或者您有根用户。 API 21-22-为了访问SD卡,您需要向用户请求