会话范围内的Spring会话+ Redis + Infinispan缓存失败

时间:2016-06-04 16:50:53

标签: spring-security spring-boot redis microservices infinispan

我使用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存储)。

任何人都可以提供帮助。

2 个答案:

答案 0 :(得分:2)

显然,缓存管理器不可序列化,因为它不应该被序列化 - 它不是数据。您必须跟踪引用SpringEmbeddedCacheManagerFactoryBean的字段并使其成为瞬态。

答案 1 :(得分:2)

您永远不应该在会话中存储Infinispan CacheManager(或缓存)。把它变成单身。

Infinispan能够在不需要Redis的情况下处理复制,只需确保启用正确的缓存模式(例如'复制'或'分发')您的用户数据将可以从所有其他节点获得,而无需在Redis中存储缓存。