我正在尝试使用 spring 为我的应用程序构建缓存服务。缓存需要从数据库填充。
我的应用程序在三个节点上运行,并希望所有三个节点都与缓存同步。如果一个节点在缓存中获得更新的值,它应该通知其他节点。
我查看了Spring Cache 抽象,它没有谈论集群环境中的缓存。
有没有办法将缓存通知传播到其他节点?
我使用 Spring Boot 版本:2.1.4.RELEASE
当我spring.cache.redis.time-to-live=20000在application.yml文件中设置时,我得到了一个例外。当我想在redis缓存中添加TTL时应该怎么做?如何在带有 Redis 的 Spring Cache 中使用缓存过期?
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR wrong number of arguments for 'set' command
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:52)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:268)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:799)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.set(LettuceStringCommands.java:180)
at org.springframework.data.redis.connection.DefaultedRedisConnection.set(DefaultedRedisConnection.java:281)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.lambda$put$0(DefaultRedisCacheWriter.java:90)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.execute(DefaultRedisCacheWriter.java:242)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.put(DefaultRedisCacheWriter.java:87)
at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:159)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:87)
at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:820)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:429)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at top.yunshu.shw.server.service.group.impl.GroupServiceImpl$$EnhancerBySpringCGLIB$$815b195d.findTeacherAllGroups(<generated>)
at top.yunshu.shw.server.controller.teacher.TeacherController.lambda$getTeacherCreateGroups$0(TeacherController.java:91)
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:323)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266) …Run Code Online (Sandbox Code Playgroud) 我想知道是否可以在 spring data mongo 存储库上使用 @Cacheable 注释。例如这样:
public interface UserRepository extends MongoRepository<User, String> {
@Cacheable("byId")
public interface UserRepository extends MongoRepository<User, String> {
User findById(String id);
}
}
Run Code Online (Sandbox Code Playgroud)
我想在接口类本身上执行此操作,并尽可能避免使用包装类。另外,是否有关于如何使用java配置(而不是xml)为redis进行缓存配置的示例?
在 Spring 应用程序(不是 spring-boot)中,我在同一个 bean 方法上使用 javanica @HystrixCommand 注释和 spring cache @Cacheable 注释,Spring 在 Hystrix 建议之前执行缓存建议。这就是我在等待的,但对我来说,没有任何配置的缓存建议和 hystrix 建议在 spring 中具有相同的顺序:LOWEST_PRECEDENCE。
我不知道是什么产生了这个订单:它是在某处定义的还是未定义的订单,我很幸运能有好的订单?必须做些什么来确保缓存建议在 Hystrix 建议之前执行(在缓存上设置顺序:在 LOWEST_PRECEDENCE 之前设置注释驱动?)
这是我的代码示例:
...
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
...
@Service
@Slf4j
@CacheConfig(cacheManager="myCacheManager")
public class MyRessourcesImpl implements MyRessources {
...
@Override
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "10000") })
@Cacheable("cacheName") //from spring cache
public Map<String, String> getTheMap() {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
使用此弹簧配置:
<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" …Run Code Online (Sandbox Code Playgroud) 使用spring-boot及其缓存机制,是否可以自动将所有作为集合返回的实体一一存储到缓存中?
例如图片下面的 Repository 方法:
@Query("...")
List<Foo> findFooByBar(Bar bar);
Run Code Online (Sandbox Code Playgroud)
我想将它们一个接一个地插入到 Spring Cache 中,这意味着会有 N 个插入(列表中的每个元素一个)而不是一个(整个列表)。
例子:
@Query("...")
@CachePut(value = "foos", key = "result.each.id")
List<Foo> findFooByBar(Bar bar);
Run Code Online (Sandbox Code Playgroud) 我有一个名为 getUserById 的方法
@Cacheable(value = "Account", key = "#accountId")
public Account getUserById(Long accountId) {
Run Code Online (Sandbox Code Playgroud)
另一个名为 getUserByIds 的方法
@Cacheable(?????)
public List<Account> getUserByIds(List<Long> accountIds) {
Run Code Online (Sandbox Code Playgroud)
如何通过帐户 ID 缓存所有帐户?谢谢
我有一个方法如下:
@Cacheable(value = "SAMPLE")
public List<SomeObj> find() {
// Method that initiates and returns the List<SomeObj> and takes around 2-3 seconds, does some logging too
}
Run Code Online (Sandbox Code Playgroud)
我正在我的配置类之一中启用缓存:
@EnableCaching
@Configuration
public SomeConf extends CachingConfigurerSupport {
// Here I also initialize my classes with @Cacheable annotation
@Bean
@Override
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Collections.singletonList((new ConcurrentMapCache("SAMPLE"))));
return cacheManager;
}
@Bean
@Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
@Bean
@Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
} …Run Code Online (Sandbox Code Playgroud) 我已经实现了一个CacheInterceptor允许通过通配符逐出缓存的自定义:
public class CustomCacheInterceptor extends CacheInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCacheInterceptor.class);
@Override
protected void doEvict(Cache cache, Object key) {
try {
// evict cache
} catch (RuntimeException ex) {
getErrorHandler().handleCacheEvictError(ex, cache, key);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在努力让它工作:
@Configuration
public class CustomProxyCachingConfiguration extends ProxyCachingConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomProxyCachingConfiguration.class);
@Bean
public CacheInterceptor cacheInterceptor() {
LOGGER.info("Creating custom cache interceptor");
CacheInterceptor interceptor = new CustomCacheInterceptor();
interceptor.setCacheOperationSources(cacheOperationSource());
if (this.cacheResolver != null) {
interceptor.setCacheResolver(this.cacheResolver);
} else if (this.cacheManager …Run Code Online (Sandbox Code Playgroud) 我有以下声明:
@Cacheable("books")
public Book findBook(ISBN isbn) {...}
Run Code Online (Sandbox Code Playgroud)
但我想每 30 分钟更新一次缓存。我知道我可以创建 @Scheduled 作业来调用带注释的方法@CacheEvict("books")
另外,我想在这种情况下,所有书籍都将被清除,但更可取的是仅更新陈旧数据(在 30 分钟前放入缓存中)
春天有什么可以促进实施的吗?
我想@Cacheable用@Timed(从千分尺)注释我的方法。但我希望@Timed仅在数据未计时的情况下应用。有没有办法做到这一点,以正确的顺序放置注释就足够了 - 那是什么顺序?
我@Timed也在使用TimedAspect,不确定这是否相关。
现在我这样做:
@Cacheable
@Timed
public String getValue(long id) {
...
}
Run Code Online (Sandbox Code Playgroud)
我找不到任何@Cacheable可以讨论这个问题的文档。
spring-cache ×10
java ×7
spring ×7
spring-boot ×5
caching ×4
redis ×2
annotations ×1
hystrix ×1
micrometer ×1