当前位置: 首页 > 知识库问答 >
问题:

Spring会话的建议Infinispan缓存模式

翟俊远
2023-03-14

我的应用程序通过Infinispan Spring Boot Starter使用Infinispan的Spring会话实现。我通过InfinispanEmbeddedHttpSessionConfiguration使用嵌入式模式。Spring会话集成留档非常稀疏,它没有提到任何关于会话缓存的推荐缓存模式的内容。

我一直在使用DIST_SYNC模式,但我注意到日志中偶尔会出现ContoptModificationException错误。是否有更合适的缓存模式,或者这可能是错误?

我使用的是Spring Boot 2.2.10、Infinispan 9.4.20和Spring Session 2.2.0。该应用程序在JDK 11下运行。

编辑

我在日志中观察到的异常如下。我已将xxx.替换为我们公司的过滤器包名称。

当同一会话被连续快速重用时,尤其是当我们的外部安全供应商在我们的应用程序上运行每周扫描时,就会出现异常。该异常并非每周都发生。当它确实发生时,它会在没有获取ConcurrentModificationException的节点上导致最终的OutOfMemory错误。堆中充满了TrianglePerCacheInboundInvocationHander$1对象。

我试图在我们的开发环境中通过运行3天的并发请求来重现这个错误,但没有成功。

我查看了Infinispan Spring会话代码,我发现每个请求都有自己的MapSession实例,它是从Infinispan中存储的序列化数据中实现的。我不知道同一会话的多个并发请求如何会导致ConcurrentModificationException,我也不知道我的应用程序中有任何地方允许从多个线程并发访问MapSession实例。

04:46:25.758 ERROR o.i.r.r.RpcManagerImpl          - ISPN000073: Unexpected error while replicating
java.util.ConcurrentModificationException: null
    at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
    at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1526)
    at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1524)
    at org.infinispan.commons.marshall.MarshallUtil.marshallMap(MarshallUtil.java:52)
    at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:63)
    at org.infinispan.marshall.exts.MapExternalizer.writeObject(MapExternalizer.java:31)
    at org.infinispan.marshall.core.GlobalMarshaller.writeInternal(GlobalMarshaller.java:638)
    at org.infinispan.marshall.core.GlobalMarshaller.writeInternalClean(GlobalMarshaller.java:643)
    at org.infinispan.marshall.core.GlobalMarshaller.lambda$findWriter$0(GlobalMarshaller.java:369)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:137)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1082)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1040)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:920)
    at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
    at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
    at org.infinispan.marshall.core.ExternalJBossMarshaller.objectToObjectStream(ExternalJBossMarshaller.java:36)
    at org.infinispan.marshall.core.GlobalMarshaller.writeRawUnknown(GlobalMarshaller.java:617)
    at org.infinispan.marshall.core.GlobalMarshaller.writeUnknown(GlobalMarshaller.java:612)
    at org.infinispan.marshall.core.GlobalMarshaller.writeNonNullableObject(GlobalMarshaller.java:412)
    at org.infinispan.marshall.core.GlobalMarshaller.writeNullableObject(GlobalMarshaller.java:355)
    at org.infinispan.marshall.core.BytesObjectOutput.writeObject(BytesObjectOutput.java:26)
    at org.infinispan.commands.triangle.SingleKeyBackupWriteCommand.writeTo(SingleKeyBackupWriteCommand.java:125)
    at org.infinispan.marshall.exts.ReplicableCommandExternalizer.writeCommandParameters(ReplicableCommandExternalizer.java:71)
    at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.marshallParameters(CacheRpcCommandExternalizer.java:118)
    at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.writeObject(CacheRpcCommandExternalizer.java:114)
    at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.writeObject(CacheRpcCommandExternalizer.java:65)
    at org.infinispan.marshall.core.GlobalMarshaller.writeInternal(GlobalMarshaller.java:638)
    at org.infinispan.marshall.core.GlobalMarshaller.writeNonNullableObject(GlobalMarshaller.java:402)
    at org.infinispan.marshall.core.GlobalMarshaller.writeNullableObject(GlobalMarshaller.java:355)
    at org.infinispan.marshall.core.GlobalMarshaller.writeObjectOutput(GlobalMarshaller.java:183)
    at org.infinispan.marshall.core.GlobalMarshaller.writeObjectOutput(GlobalMarshaller.java:176)
    at org.infinispan.marshall.core.GlobalMarshaller.objectToBuffer(GlobalMarshaller.java:305)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.marshallRequest(JGroupsTransport.java:1031)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.sendCommand(JGroupsTransport.java:1217)
    at org.infinispan.remoting.transport.jgroups.JGroupsTransport.sendToMany(JGroupsTransport.java:276)
    at org.infinispan.remoting.rpc.RpcManagerImpl.sendToMany(RpcManagerImpl.java:390)
    at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.sendToBackups(TriangleDistributionInterceptor.java:490)
    at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.lambda$localPrimaryOwnerWrite$4(TriangleDistributionInterceptor.java:443)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenApply(BaseAsyncInterceptor.java:82)
    at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.localPrimaryOwnerWrite(TriangleDistributionInterceptor.java:422)
    at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.handleSingleKeyWriteCommand(TriangleDistributionInterceptor.java:392)
    at org.infinispan.interceptors.distribution.TriangleDistributionInterceptor.visitPutKeyValueCommand(TriangleDistributionInterceptor.java:113)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:55)
    at org.infinispan.interceptors.BaseAsyncInterceptor.lambda$new$0(BaseAsyncInterceptor.java:23)
    at org.infinispan.interceptors.InvocationSuccessFunction.apply(InvocationSuccessFunction.java:25)
    at org.infinispan.interceptors.impl.SimpleAsyncInvocationStage.addCallback(SimpleAsyncInvocationStage.java:70)
    at org.infinispan.interceptors.InvocationStage.thenApply(InvocationStage.java:45)
    at org.infinispan.interceptors.BaseAsyncInterceptor.asyncInvokeNext(BaseAsyncInterceptor.java:225)
    at org.infinispan.interceptors.impl.EntryWrappingInterceptor.setSkipRemoteGetsAndInvokeNextForDataCommand(EntryWrappingInterceptor.java:734)
    at org.infinispan.interceptors.impl.EntryWrappingInterceptor.visitPutKeyValueCommand(EntryWrappingInterceptor.java:337)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:151)
    at org.infinispan.interceptors.locking.AbstractLockingInterceptor.lambda$nonTxLockAndInvokeNext$1(AbstractLockingInterceptor.java:297)
    at org.infinispan.interceptors.SyncInvocationStage.addCallback(SyncInvocationStage.java:42)
    at org.infinispan.interceptors.InvocationStage.andHandle(InvocationStage.java:65)
    at org.infinispan.interceptors.locking.AbstractLockingInterceptor.nonTxLockAndInvokeNext(AbstractLockingInterceptor.java:292)
    at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitNonTxDataWriteCommand(AbstractLockingInterceptor.java:128)
    at org.infinispan.interceptors.locking.NonTransactionalLockingInterceptor.visitDataWriteCommand(NonTransactionalLockingInterceptor.java:40)
    at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitPutKeyValueCommand(AbstractLockingInterceptor.java:82)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndHandle(BaseAsyncInterceptor.java:184)
    at org.infinispan.statetransfer.StateTransferInterceptor.handleNonTxWriteCommand(StateTransferInterceptor.java:309)
    at org.infinispan.statetransfer.StateTransferInterceptor.handleWriteCommand(StateTransferInterceptor.java:252)
    at org.infinispan.statetransfer.StateTransferInterceptor.visitPutKeyValueCommand(StateTransferInterceptor.java:96)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:151)
    at org.infinispan.interceptors.impl.CacheMgmtInterceptor.updateStoreStatistics(CacheMgmtInterceptor.java:220)
    at org.infinispan.interceptors.impl.CacheMgmtInterceptor.visitPutKeyValueCommand(CacheMgmtInterceptor.java:182)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:55)
    at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
    at org.infinispan.interceptors.DDAsyncInterceptor.visitPutKeyValueCommand(DDAsyncInterceptor.java:60)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:124)
    at org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90)
    at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:57)
    at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
    at org.infinispan.interceptors.DDAsyncInterceptor.visitPutKeyValueCommand(DDAsyncInterceptor.java:60)
    at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:73)
    at org.infinispan.interceptors.DDAsyncInterceptor.visitCommand(DDAsyncInterceptor.java:50)
    at org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248)
    at org.infinispan.cache.impl.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:1915)
    at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:1430)
    at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:2040)
    at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:1415)
    at org.infinispan.cache.impl.CacheImpl.put(CacheImpl.java:235)
    at org.infinispan.cache.impl.AbstractDelegatingCache.put(AbstractDelegatingCache.java:116)
    at org.infinispan.cache.impl.EncoderCache.put(EncoderCache.java:195)
    at org.infinispan.spring.common.provider.SpringCache.put(SpringCache.java:159)
    at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.updateTTL(AbstractInfinispanSessionRepository.java:112)
    at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.lambda$getSession$1(AbstractInfinispanSessionRepository.java:105)
    at java.base/java.util.Optional.map(Optional.java:265)
    at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.getSession(AbstractInfinispanSessionRepository.java:105)
    at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.findById(AbstractInfinispanSessionRepository.java:79)
    at org.infinispan.spring.common.session.AbstractInfinispanSessionRepository.findById(AbstractInfinispanSessionRepository.java:32)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSession(SessionRepositoryFilter.java:351)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:289)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:192)
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244)
    at xxx.MaxSimultaneousRequestsFilter.getKey(MaxSimultaneousRequestsFilter.java:266)
    at xxx.MaxSimultaneousRequestsFilter.doFilter(MaxSimultaneousRequestsFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at xxx.LoginFilter.doFilter(LoginFilter.java:49)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at xxx.BigIPFilter.doFilter(BigIPFilter.java:41)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at xxx.EncodingFilter.doFilter(EncodingFilter.java:36)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:141)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at xxx.ExcludeSessionRepositoryFilter.doFilter(ExcludeSessionRepositoryFilter.java:78)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.jboss.marshalling.TraceInformation: null

共有1个答案

邓元白
2023-03-14

对会话使用DIST\u同步模式应该可以。

如果在序列化会话属性时抛出ConcurrentModificationException,则表明应用程序在会话中插入属性值后正在修改属性值,而不应这样做。

如果在序列化会话本身时发生ConvoltModificationException,那么它很可能是Infinispan Spring会话集成中的错误。如果ContoptModificationException与序列化完全无关,也是如此。我建议在您的问题中发布完整的堆栈跟踪,或者为Infinispan Zulip Chat注册一个帐户并在那里发布异常。

最后要指出的是,Infinispan 9.4.20非常古老,最终的bug修复可能只会在Infinispan 12中实现。十、

 类似资料:
  • 我使用Infinispan缓存作为会话作用域bean,在Spring MVC应用程序中缓存与用户相关的数据对象。 现在我们迁移到Spring引导,我们想使用@enableRedisHttp会话,但我们面临的问题是,附加到会话的InfinispanCacheManager是不可序列化的,产生以下异常: 通常,我们会平衡用户对多个节点的请求,因此需要在节点之间共享缓存(使用Redis store)。

  • 在我正在开发的应用程序中,我使用了Spring JMS DefaultMessageListenerContainer和作为SessionAwareMessageListener的JMS使用者。还有一个XA transactionManager,在JMS和JDBC之间共享。作为JMS提供者,我使用WebLogic。 我注意到,每次消费者收到一条消息时,JMS会话都与之前消息中使用的会话完全不同:

  • 我有两个应用程序使用相同的数据库实体。这两个应用程序都部署在jboss eap 6.2独立的集群上。DB表仅从一个应用程序中更新,但从两个应用程序中读取。这两个应用程序都使用本机hibernate API从数据库读取/写入数据。 在嵌入式模式下将infinispan启用为2LC后,如何确保在一个应用程序中更新的缓存实体从第二个应用程序缓存中失效?是否有任何JMX/JMS接口用于信号缓存失效? 若我

  • 我是infinispan的新手,通过实验学习。在尝试访问不同名称的远程缓存失败后,我需要一些帮助。下面是我的infinispan客户端-服务器模式未嵌入的场景。 1) 我在infinispan集群中启动了node1,并将默认远程缓存名称设置为node1\u cache--Hotrod服务器已启动 2) 已在infinispan群集中启动node2,并将默认远程缓存名称设置为node2\u cach

  • 在Infinispan 6.0中。有x版本,但wildfly 8.2的属性是什么? 谢啦

  • 我们目前正在使用下面的。它很旧,但现在无法升级到更高版本 我们已经将代码从直接JDG实现(如下所示)修改为基于XML的配置文件中的SpringRemteCacheManager,并使用Spring cache:建议来定义可缓存、cahce-put、cache-evict方法。 请参阅当前代码,其中我们可以控制添加到期时间。我们也想用Spring-Infinispan做类似的事情。使用Spring-