问题标签 [caffeine]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
spring-boot - 使用 Spring Cacheable 的 L1 + L2 缓存策略
我正在尝试设置 L1 + L2 缓存策略以与@Cacheable
注释一起使用。我的目标是
- 配置咖啡因缓存
- 配置 Redis 缓存
- 在咖啡因缓存中查找项目,如果找到返回,否则步骤 4
- 在 Redis 缓存中查找项目,如果找到返回并缓存在咖啡因中,否则步骤 5
- 使用真实服务返回结果。
我知道开箱即用不支持此功能,但我一直在尝试阅读有关如何连接此类解决方案的文档。
我目前的解决方案是包装我的实际服务是 a RedisBackedService
,它具有redisCacheManager
oncacheable
注释,而该服务又被包装在CaffeineBackedService
具有 a注释的 acaffeineCacheManager
中cacheable
。不用说,这似乎是多余的。
任何指针都会有所帮助。
spring - @Cacheable 和启动期间的初始化
我想在我的 Spring Boot 应用程序启动期间初始化缓存中的所有条目(从 DB 加载内容)。理想情况下,这是在应用程序准备好之前完成的。所以我实现了所有的加载@PostConstruct
。我说,缓存尚未设置@PostContruct
,我按照一些提示在ApplicationReadyEvent
. 但是,这仍然无法按预期工作:
即使我已经在 中调用了一个@Cacheable
方法ApplicationReadyEvent
,第二次调用也会重新进入该方法而不是使用缓存。
我的服务:
我的咖啡因 CacheManager 配置:
使用该服务的简单 REST 端点:
如果我启动应用程序并执行两个GET /test
,我会得到以下输出:
那么为什么第二次调用MyService.getEntry
(即“Startup”之后的第一次调用)又进入了代码呢?
最后,我需要一个解决方案,它在应用程序完成启动之前执行第一次加载 - 即我将尝试ContextRefreshedEvent
或再次尝试@PostConstruct
(并@Autowire CacheManager
在执行之前对其进行配置@PostConstruct
)。但第一步是让这个示例在此处按预期运行。
spring - 咖啡因缓存 refreshAfterWrite 方法抛出 refreshAfterWrite 需要 LoadingCache 异常
我需要通过再次调用 API 来重新缓存过期的缓存
以下是我的缓存管理器配置
但是在启动应用程序时,它会抛出以下异常
原因:java.lang.IllegalStateException: refreshAfterWrite 需要 LoadingCache
spring-boot - spring cloud config刷新缓存配置
考虑以下服务,我如何使用/actuator/refresh端点动态修改缓存配置
使用以下默认配置
假设设置为maximumSize=50,expireAfterAccess=300s
在GreetingService中添加@RefreshScope不起作用。不知何故,我需要指示 Spring Boot 重新创建 CacheManager?
我在这里有一个支持项目:
- https://github.com/altfatterz/refreshscope-demo
- https://github.com/altfatterz/refreshscope-demo-config
谢谢。
java - 是否有用于咖啡因缓存的 CacheEntryExpiredListener?
我知道Cache2k
只有CacheEntryExpiredListener
在缓存条目自行过期时才会触发(而不是在显式无效时)。
问题:如何使用caffeine
缓存实现来实现相同的目标?
spring-webflux - 使用 Reactor 和咖啡因时缓存无法正常工作
我需要以不同的时间间隔检查一些端点,所以我设置了 Caffeine 的缓存构建器。
this.localeWeatherCache = newBuilder().build();
this.currentWeatherCache=newBuilder().expireAfterWrite(Duration.ofHours(3)).build();
this.weatherForecastsCache = newBuilder().expireAfterWrite(Duration.ofHours(12)).build();
在我的服务中,我调用这 3 个端点,最后我使用 Mono.zip() 返回包含所有详细信息的对象。
在我的测试中,我注意到climaTempoRepository.findLocaleByCityNameAndState 执行了两次,并且在currentWeather缓存过期后,它再次调用locale端点,weatherForecast 也是如此,它再次调用locale。
为什么会失败?它不应该使用缓存吗?还是我的做法不对?
非常感谢任何帮助或指示!:)
kotlin - 如何在 Kotlin 协程中使用异步缓存?
我有一个使用协程的 Kotlin JVM 服务器应用程序,我需要在非阻塞网络调用前面放置一个缓存。我想我可以使用咖啡因AsyncLoadingCache
来获得我需要的非阻塞缓存行为。AsyncCacheLoader
我需要实现的接口使用CompletableFuture
. 同时,我要调用的加载缓存条目的方法是一个suspend
函数。
我可以像这样弥合差距:
这将在提供的(默认情况下, the )上运行该load
函数,从 Caffeine 的角度来看,这是正确的行为。Executor
ForkJoinPool
但是,我知道我应该尽量避免使用 GlobalScope 来启动 coroutines。
我考虑让我的SuspendingCacheLoader
实现CoroutineScope
和管理自己的协程上下文。但CoroutineScope
旨在由具有托管生命周期的对象实现。缓存和 都没有AsyncCacheLoader
任何生命周期钩子。缓存拥有Executor
和CompletableFuture
实例,因此它已经以这种方式控制了加载任务的生命周期。我看不出让协程上下文拥有任务会添加任何东西,而且我担心在缓存停止使用后我将无法正确关闭协程上下文。
编写自己的异步缓存机制非常困难,所以如果可以的话,我想与 Caffeine 实现集成。
是使用GlobalScope
正确的方法来实现AsyncCacheLoader
,还是有更好的解决方案?
java - Caffeine LoadingCache 实现的单元测试单独通过,但一起运行时失败
我为我的 Caffeine CacheLoader 实现编写的单元测试(JUnit、Mockito)在我单独运行它们时都成功了,但是当我一起运行它们时其中一个会失败。我相信我在使用@Before
我的所有测试对象设置时都遵循了最佳实践。
与其他人一起运行时,测试testGet_WhenCalledASecondAndThirdTimeBeyondCacheDuration_LoadingMethodCalledASecondTime每次都会失败,并出现以下错误:
在测试之间似乎有些东西会延续,但考虑到我在我的@Before
方法中所做的事情,我不确定这是怎么回事。我尝试在@After
方法中调用以下内容:
invalidateAll()
cleanUp()
Mockito.reset(testDataSource)
我还尝试手动将 a 传递singleThreadExecutor
给缓存构建器,并等待它完成它正在做的@After
任何事情,以防万一与它有关。
reload
如果尝试刷新它失败(抛出异常),我的 Caffeine CacheLoader 实现只是覆盖返回当前缓存值的方法。除此之外,它很香草。
java - 咖啡因缓存始终使用 getIfPresent 方法返回 null
我正在尝试实现咖啡因缓存以避免暴力登录尝试。这样我就有了一个缓存,其中键 = IP 地址,值 = 登录尝试次数。
我有一个服务,它构建咖啡因缓存和一些方法来处理登录失败和成功事件。如果用户提供了错误的凭据,则loginFailed(String key)
调用方法。但是,getIfPresent(key)
即使 put 方法有效,也始终返回 null。
顺便说一下,IP 地址来自AuthenticationFailureListener组件。
我曾尝试使用 Google 的 Guava Cache,但它已被弃用并被咖啡因取代。
登录尝试服务
上面的代码,我期望当isBlocked(String key)
方法被调用时,它应该返回给定键的尝试次数,即 IP 地址。
编辑:我实际上已经找到了问题。如果我不expireAfterWrite
使用咖啡因生成器,它会很好用。但我不知道为什么它不起作用。