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

在Spring WebFlux web应用程序中缓存WebClient调用的单声道结果

章兴发
2023-03-14

我希望缓存一个单字(只有在成功的情况下),这是WebClient调用的结果。

通过阅读reactor addons项目文档,我不觉得CacheMono是一个很好的适合,因为它也缓存了错误,这是我不想要的。

因此,我不使用cachemono,而是执行以下操作:

Cache<MyRequestObject, Mono<MyResponseObject>> myCaffeineCache = 
    Caffeine.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(Duration.ofSeconds(60))
            .build();

MyRequestObject myRequestObject = ...;

Mono<MyResponseObject> myResponseObject = myCaffeineCache.get(myRequestObject,
    requestAsKey -> WebClient.create()
                             .post()
                             .uri("http://www.example.com")
                             .syncBody(requestAsKey)
                             .retrieve()
                             .bodyToMono(MyResponseObject.class)
                             .cache()
                             .doOnError(t -> myCaffeineCache.invalidate(requestAsKey)));

共有1个答案

袁高峰
2023-03-14

这是少数几个实际允许调用非反应库并用反应类型包装它们的用例之一,并在doonxyz等副作用操作符中进行处理,因为:

  • 咖啡因是内存中的缓存,所以据我所知不涉及I/O
  • 缓存通常不能为缓存值提供强有力的保证(这是非常“开火就忘了”)

在本例中,您可以查询缓存以查看是否存在缓存版本(包装并立即返回),并在doon运算符中缓存成功的实际响应,如下所示:

public class MyService {

    private WebClient client;

    private Cache<MyRequestObject, MyResponseObject> myCaffeineCache;

    public MyService() {
        this.client = WebClient.create();
        this.myCaffeineCache = Caffeine.newBuilder().maximumSize(100)
          .expireAfterWrite(Duration.ofSeconds(60)).build();
    }

    public Mono<MyResponseObject> fetchResponse(MyRequestObject request) {

        MyResponseObject cachedVersion = this.myCaffeineCache.get(myRequestObject);
        if (cachedVersion != null) {
           return Mono.just(cachedVersion);
        } else {
           return this.client.post()
                         .uri("http://www.example.com")
                         .syncBody(request.getKey())
                         .retrieve()
                         .bodyToMono(MyResponseObject.class)
                         .doOnNext(response -> this.myCaffeineCache.put(request.getKey(), response));
    }
}
 类似资料:
  • 问题方法需要等待单声道操作结果,在通量操作中使用,并返回通量。 研究我希望流被Mongo反应驱动订阅并终止,所以我不订阅。如果我使用我有单声道 任务如何等待值,在通量操作中使用它并从中获取通量?

  • 我正在Kotlin中构建一个小型Spring WebFlux应用程序的原型。这个应用程序需要从远程RESTendpoint获取一个tar归档文件,并将其存储在本地磁盘上。听起来很简单。 我首先创建了一个集成测试,它启动spring服务器和一个带有模拟RESTendpoint的WebFlux服务器,该endpoint为tar存档提供服务。 测试应该是这样的: 1)app:GET 2)mock-ser

  • 主要内容:什么是应用程序缓存(Application Cache)?,浏览器支持,HTML5 Cache Manifest 实例,实例,Cache Manifest 基础,Manifest 文件,更新缓存,实例 - 完整的 Manifest 文件,关于应用程序缓存的说明使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。 注意:manifest 的技术已被 web 标准废弃,不再推荐使用此功能。 什么是应用程序缓存(Application Ca

  • 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。 什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。 应用程序缓存为应用带来三个优势: 离线浏览 - 用户可在应用离线时使用它们 速度 - 已缓存资源加载得更快 减少服务器负载 - 浏览器

  • 我在web应用程序中使用Spring、WebFlux和WebClient。 我的应用程序可能会调用'N'数量的其他微服务,这些服务也是由我们托管的。 现在的问题是,我想限制我的WebClient对现有微服务同时调用有限数量的调用。

  • 嗨我刚开始学习反应式编程 我这里有这段代码,我的过程应该是我将调用TokenRepository来获取令牌,然后使用token.getAccessToken()作为cardRepository.findAllCards()上的参数 想知道这是否可行吗?

  • 更新我的Android应用程序的www文件夹(使用Cordova 3.6.3)时,该应用程序会显示我的www的旧缓存版本。 如果我清除应用程序数据(来自Android- 当应用程序更新时(或每次应用程序启动时),如何强制应用程序清除缓存?

  • 问题内容: 我想在python中创建一个redis缓存,作为任何自尊的科学家,我都做了一个基准测试性能。 有趣的是,redis的表现并不那么好。Python做一些不可思议的事情(存储文件),或者我的redis版本太慢了。 我不知道这是否是因为我的代码的结构方式或原因,但是我希望redis比它做得更好。 为了进行Redis缓存,我将二进制数据(在本例中为HTML页面)设置为从文件名派生的密钥,有效期