Java 被动:缓存服务响应数小时
因此,我的应用程序将多次调用下面昂贵的HTTP服务(同时由多个线程使用相同和不同的ID对我的应用程序的每个客户端请求进行调用) 然后呢,Java 被动:缓存服务响应数小时,java,spring,spring-webflux,project-reactor,Java,Spring,Spring Webflux,Project Reactor,因此,我的应用程序将多次调用下面昂贵的HTTP服务(同时由多个线程使用相同和不同的ID对我的应用程序的每个客户端请求进行调用) 然后呢, public Mono<Foo> get(String id){ Foo cachedFoo = getFromCacheSolution(id); if(cachedFoo != null){ return Mono.just(cachedFoo); } else{ return myService
public Mono<Foo> get(String id){
Foo cachedFoo = getFromCacheSolution(id);
if(cachedFoo != null){
return Mono.just(cachedFoo);
}
else{
return myService.fetch(id).doOnNext(value->storeToCacheSolution(id, value)); //line 7
}
}
public Mono<Foo> get(String id){
return getFromCacheSolution(id).switchIfEmpty(Mono.defer(()->
{
cachedResponse = myService.fetch(id).doOnNext(value->storeToCacheSolution(id, value));
return cachedResponse;
}));
}
public Mono-get(字符串id){
Foo cachedFoo=getFromCacheSolution(id);
if(cachedFoo!=null){
返回Mono.just(cachedFoo);
}
否则{
返回myService.fetch(id).doOnNext(value->storeToCacheSolution(id,value));//第7行
}
}
此解决方案的问题是,第7行将被多次调用,从而导致对昂贵的获取服务的多次调用(例如,如果3个线程进入id为123的get方法,并且cachedFoo为null)。使方法同步可能没有帮助,因为第7行将立即完成
解决方法之一是将Mono存储在缓存解决方案中,而不是存储在Foo中(不确定这是否是一个好主意):
Mono getFromCacheSolution(字符串id)//返回缓存的或空的Mono
然后呢,
public Mono<Foo> get(String id){
Foo cachedFoo = getFromCacheSolution(id);
if(cachedFoo != null){
return Mono.just(cachedFoo);
}
else{
return myService.fetch(id).doOnNext(value->storeToCacheSolution(id, value)); //line 7
}
}
public Mono<Foo> get(String id){
return getFromCacheSolution(id).switchIfEmpty(Mono.defer(()->
{
cachedResponse = myService.fetch(id).doOnNext(value->storeToCacheSolution(id, value));
return cachedResponse;
}));
}
public Mono-get(字符串id){
返回getFromCacheSolution(id).switchIfEmpty(Mono.defer)(()->
{
cachedResponse=myService.fetch(id).doOnNext(value->storeToCacheSolution(id,value));
返回缓存响应;
}));
}
有什么建议或更好的选择吗?您的问题包括两部分:关于缓存和关于使用相同参数的调用的独占锁定
CacheMono
monomyfoo=
CacheMono.lookup(key->Mono.justOrEmpty(myCache.getIfPresent(key))
.map(信号::下一步),id)
.onCacheMissResume(()->myService.fetch(id))
.并使用((键、信号)->Mono.fromRunnable(()->
可选.ofNullable(signal.get())
.ifPresent(value->myCache.put(key,value));
我更喜欢第二个解决方案,但也许反应堆额外项目能在这里有所帮助?
Mono<Foo> getFromCacheSolution(String id); //returns cached or empty Mono
public Mono<Foo> get(String id){
return getFromCacheSolution(id).switchIfEmpty(Mono.defer(()->
{
cachedResponse = myService.fetch(id).doOnNext(value->storeToCacheSolution(id, value));
return cachedResponse;
}));
}