Java Spring引导-使用动态TTL周期逐出缓存

Java Spring引导-使用动态TTL周期逐出缓存,java,spring-boot,guava,spring-cache,Java,Spring Boot,Guava,Spring Cache,在我的微服务(SERVICE-A)中,我对另一个微服务(SERVICE-B)进行RESTAPI调用,以进行登录并获取访问令牌,该api将使用该令牌的TTL进行响应。 我需要缓存令牌,直到SERVICE-B响应的TTL(秒)为止。因此我的实现如下所示 @Cacheable("USERTOKEN") public String getUserToken() { //Hits Service-B //Gets token and TTL as a response from

在我的微服务(SERVICE-A)中,我对另一个微服务(SERVICE-B)进行RESTAPI调用,以进行登录并获取访问令牌,该api将使用该令牌的TTL进行响应。 我需要缓存令牌,直到SERVICE-B响应的TTL(秒)为止。因此我的实现如下所示

@Cacheable("USERTOKEN")
public String getUserToken()
{
  //Hits Service-B
  //Gets token and TTL as a response from Service-B
  //Returns Token or Token with TTL
}
我需要改变上面的方法

@Cacheable("USERTOKEN")
public String getUserToken()
{
  //Hits Service-B
  //Gets token and TTL as a response from Service-B
  //Sets expiry time for "USERTOKEN" cache   <-- this needs to be added
  //Returns Token or Token with TTL
}
@Cacheable(“USERTOKEN”)
公共字符串getUserToken()
{
//点击服务-B
//从服务B获取令牌和TTL作为响应

//设置“USERTOKEN”缓存的过期时间您正在使用哪个缓存服务

如果您使用Redis cache,他们会为此提供许多命令:

:设置按键的超时。 :与上一个相同,但采用绝对Unix时间戳(自1970年1月1日起的秒数)。 :返回具有超时的密钥的剩余生存时间 关于Redis上的过期,您必须知道一件重要的事情:只有在使用SET或GETSET删除或覆盖密钥时,才会清除超时值。所有其他命令(INCR、LPUSH、HMSET等)都不会更改初始超时

绝对过期是Redis使用EXPIRE的本机功能。要实现滑动过期,只需在每个命令后重置为超时值

一个基本的方法是

MULTI
GET MYKEY
EXPIRE MYKEY 60
EXEC

如果您使用的是Spring的默认实现,您将无法设置缓存TTL。但对于其他提供程序,如EhCache、Gemfire和Guava,您可以这样做,但只能在配置缓存管理器时进行。对于

像这样-对于Ehcache

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
  .with(CacheManagerBuilder.persistence(tmpDir.newFile("myData")))
  .withCache("threeTieredCache",
    CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
      ResourcePoolsBuilder.newResourcePoolsBuilder()
        .heap(10, EntryUnit.ENTRIES)
        .offheap(1, MemoryUnit.MB)
        .disk(20, MemoryUnit.MB, true))
      .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(20)))
  ).build(false);

Configuration configuration = cacheManager.getRuntimeConfiguration();
XmlConfiguration xmlConfiguration = new XmlConfiguration(configuration);  
String xml = xmlConfiguration.toString(); 
火烧

<gfe:region-template id="BaseRegionTemplate" initial-capacity="51" load-factor="0.85" persistent="false" statistics="true"
      key-constraint="java.lang.Long" value-constraint="java.lang.String">
    <gfe:cache-listener>
      <bean class="example.CacheListenerOne"/>
      <bean class="example.CacheListenerTwo"/>
    </gfe:cache-listener>
    <gfe:entry-ttl timeout="600" action="DESTROY"/>
    <gfe:entry-tti timeout="300 action="INVLIDATE"/>
  </gfe:region-template>

如果使用,则可以使用不同的过期策略:

发件人:

//根据不同的过期策略退出
LoadingCache graphs=caffee.newBuilder()
.到期日(新到期日){
public long expireAfterCreate(键、图形、长currentTime){
//如果来自外部资源,则使用挂钟时间,而不是纳米时间
长秒=graph.creationDate().plusHours(5)
.减号(System.currentTimeMillis(),毫秒)
.toepochssecond();
返回时间单位。秒。托纳诺斯(秒);
}
public long expireAfterUpdate(密钥、图形、,
长currentTime,长currentDuration){
返回持续时间;
}
public long expireAfterRead(键、图形、,
长currentTime,长currentDuration){
返回持续时间;
}
})
.build(key->createExpensiveGraph(key));

什么是您的缓存提供程序和缓存存储?您使用的是spring的默认缓存管理器吗?是的..spring的默认缓存管理器。我尝试了Guava,但即使在该过期期内,也只能在使用@Cacheable..rite之前进行设置。是的,您是正确的。根据第
8.7节。我如何设置TTL/TTI/逐出策略/XXX功能?
。spring这样做没有这个功能,因为它提供了抽象缓存实现,您可以使用不同的缓存提供程序(如Redis)来实现
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumSize(10_000)
    .expireAfterWrite(5, TimeUnit.MINUTES)
    .refreshAfterWrite(1, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));