如何解决反应式应用程序中的 Spring Cache
我使用的是 Spring Cache 默认实现(ConcurrentHashMap):
@Bean
CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager("mycache");
cacheManager.setAllowNullValues(false);
return cacheManager;
}
Reactor addons 用于获取物品。缓存未命中项写入缓存:
public Mono<T> get(ID key) {
return CacheMono.lookup(k -> findValue(k).map(Signal::next),key)
.onCacheMissResume(Mono.defer(valueRetriever(key)))
.andWriteWith((k,signal) -> Mono.fromRunnable(() -> {
if (!signal.isOnError()) {
writeValue(k,signal.get());
}
}));
}
private void writeValue(ID key,T value) {
if (value != null) {
cache.put(key,value);
}
}
cache.put(key,value);
是否视为阻塞调用?应该在不同的调度程序上发布吗?
解决方法
是的。
如果有机会,我建议您改用带有 Lettuce 的 ReactiveRedisConnection。
例如,您可以按如下方式设置 bean:
@Bean
public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
final RedisStandaloneConfiguration redisConfig
= new RedisStandaloneConfiguration(SpringBootApp.redisHost,SpringBootApp.redisPort);
redisConfig.setPassword(SpringBootApp.redisPassword);
redisConfig.setDatabase(0);
final LettuceConnectionFactory connFac = new LettuceConnectionFactory(redisConfig);
return connFac;
}
@Bean
public ReactiveRedisConnection reactiveRedisConnection(final ReactiveRedisConnectionFactory redisConnectionFactory) {
return redisConnectionFactory.getReactiveConnection();
}
@Bean
public ReactiveRedisOperations<String,Object> redisOperations(ReactiveRedisConnectionFactory factory) {
final JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
final RedisSerializationContext.RedisSerializationContextBuilder<String,Object> builder = RedisSerializationContext
.newSerializationContext(new StringRedisSerializer());
final RedisSerializationContext<String,Object> context = builder.value(serializer).build();
return new ReactiveRedisTemplate<>(factory,context);
}
然后您可以使用 ReactiveRedisOperations
从非阻塞缓存中存储/检索您的数据。你可以这样做:
Mono.just("my_cache_key::" + uniqueId)
.flatMap(key -> reactiveRedisOps.opsForValue().get(key)
.cast(MyObj.class)
.switchIfEmpty(
getMyObjNonBlocking()
.flatMap(myObj -> ops.opsForValue().set(key,myObj,Duration.ofMinutes(ttl))
.thenReturn(myObj))
));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。