Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 被动:缓存服务响应数小时_Java_Spring_Spring Webflux_Project Reactor - Fatal编程技术网

Java 被动:缓存服务响应数小时

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

因此,我的应用程序将多次调用下面昂贵的HTTP服务(同时由多个线程使用相同和不同的ID对我的应用程序的每个客户端请求进行调用)

然后呢,

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;
        }));
    }