Java Spring引导-使用动态TTL周期逐出缓存
在我的微服务(SERVICE-A)中,我对另一个微服务(SERVICE-B)进行RESTAPI调用,以进行登录并获取访问令牌,该api将使用该令牌的TTL进行响应。 我需要缓存令牌,直到SERVICE-B响应的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
@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));