我使用Infinispan缓存作为会话范围bean来缓存Spring MVC应用程序中与用户相关的数据对象。
现在我们迁移到spring boot,我们想使用@enableRedisHttpSession 但我们面临的问题是附加到会话的Infinispan CacheManager不是Serializable,产生以下异常:
java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [org.infinispan.spring.provider.SpringEmbeddedCacheManagerFactoryBean]
org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43)
org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63)
org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35)
org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:50)
org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:166)
org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:128)
org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:85)
org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:409)
org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:331)
org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:211)
org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:141)
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:193)
org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:169)
org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:127)
org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
通常我们会将用户请求与多个节点进行平衡,因此我们需要在节点之间共享缓存(使用Redis存储)。
任何人都可以提供帮助。
答案 0 :(得分:2)
显然,缓存管理器不可序列化,因为它不应该被序列化 - 它不是数据。您必须跟踪引用SpringEmbeddedCacheManagerFactoryBean
的字段并使其成为瞬态。
答案 1 :(得分:2)
您永远不应该在会话中存储Infinispan CacheManager(或缓存)。把它变成单身。
Infinispan能够在不需要Redis的情况下处理复制,只需确保启用正确的缓存模式(例如'复制'或'分发')您的用户数据将可以从所有其他节点获得,而无需在Redis中存储缓存。