为什么我只在部署了完全相同的三个Web服务器中的1个上才获得ConcurrentModificationException

问题描述 投票:0回答:2

我们在三个相同的WebLogic服务器上部署了一个Peoplesoft应用程序。 Netscaler设备在它们之间进行负载平衡并保持会话的粘性。交付的Peoplesoft ear应用程序由Oracle交付,未经我们任何方式定制。

三个Web服务器之一显示ConcurrentModificationExceptions。我们在企业中的许多其他服务器上部署了相同的耳朵,但这是唯一遇到此问题的服务器。这个问题是如此严重,以至于我们不得不使服务器停机并脱离服务器场。因此,现在我们在原始3台服务器中的2台上进行负载平衡。

作为Oracle的客户,我们无权访问任何源代码。这使得很难缩小问题的范围。

由于此耳朵与运行正常的服务器上的耳朵完全相同,所以我认为“差异”一定是引起问题的耳朵之外的东西。

这是我想出的:

当应用程序试图从JOLT连接池中获取线程时,发生异常。该池由一个Java链表对象管理。该线程尝试遍历链接列表,以查找可用的连接来连接到App Server。 (背景:Peoplesoft的耳朵(部署在WebLogic App Server中)使用JOLT连接到另一层(由C ++和Java代码组成的应用程序,它们通过Tuxedo控制的IPC对象(例如队列,共享内存...)进行通信。为提高效率而进行池化。在从池分配连接之前,该线程失败。另一个线程(我认为)在链表上进行迭代,然后导致ConcurrentModificationException。

某些线程能够从缓冲池成功获取连接,但是当流量增加时,会发生ConcurrentModificationException的可能性。

[当我说我检查了某件事时,我的意思是我将它们与服务器上相同的项目进行了比较,没有问题

我已经检查了很多东西以寻找原因:

  • 已检查并重新安装的weblogic
  • 已检查并重新安装的peopletools
  • 检查并重新部署了Peoplesoft应用程序
  • 检查并重新安装Java
  • 使用了Java的不同版本
  • 检查类路径
  • 检查环境变量
  • 已检查限制
  • 已检查Java命令行选项
  • 已检查操作系统版本,技术级别和Service Pack版本
  • 已检查操作系统文件集

我对要检查的内容没有足够的想法。

java.util.ConcurrentModificationException       java.util.ConcurrentModificationException<br>^M
        at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:977)^M
        at java.util.LinkedList$ListItr.next(LinkedList.java:899)^M
        at psft.pt8.net.JoltSessionPool.getJoltSession(JoltSessionPool.java:276)^M
        at psft.pt8.net.NetSession.getJoltSession(NetSession.java:693)^M
        at psft.pt8.net.NetReqRepSvc.sendRequest(NetReqRepSvc.java:556)^M
        at psft.pt8.net.NetService.requestService(NetService.java:167)^M
        at psft.pt8.net.NetReqRepSvc.requestService(NetReqRepSvc.java:354)^M
        at psft.pt8.jb.JBEntry.processRequest(JBEntry.java:673)^M
        at psft.pt8.psc.onActionGen(psc.java:3045)^M
        at psft.pt8.psc.onAction(psc.java:1753)^M
        at psft.pt8.psc.onAction(psc.java:1742)^M
        at psft.pt8.psc.service(psc.java:963)^M
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)^M
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)^M
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)^M
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)^M
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)^M
        at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)^M
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)^M
        at weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilter.java:274)^M
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)^M
        at psft.pt8.psfilter.doFilter(psfilter.java:88)^M
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)^M
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3706)^M
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3672)^M
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:328)^M
        at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)^M
        at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)^M
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)^M
        at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2443)^M
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2291)^M
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2269)^M
        at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1705)^M
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1665)^M
        at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:272)^M
        at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)^M
        at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)^M
        at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)^M
        at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)^M

什么,在Java耳朵之外可能会影响此?

java multithreading linked-list iterator concurrentmodification
2个回答
0
投票

ConcurrentModificationException几乎总是编码错误。该代码没有为运行中的多个线程准备,或者存在缺陷。不幸的是,这可能是随机发生的,例如当两个线程试图同时修改资源时。另一种情况是单线程使用快速失败迭代器修改当前正在迭代的资源。第二种情况将可预测地发生。

另一个线程(我假设)遍历链表,然后导致ConcurrentModificationException。

另一个线程可能必须通过添加或删除元素来修改链表。这是一个编码疏忽。

  1. 您是否与提供peoplesoft的软件公司联系?他们需要修复其代码并使psft.pt8.net.JoltSessionPool.getJoltSession(JoltSessionPool.java:276)线程安全。
  2. 此服务器的另一种选择是仅使用一个工作线程运行它。 (为Java程序配置,因此它不会打开多个Java线程。)在软件开发人员修复错误之前,这可能是一个临时解决方案。
  3. 验证weblogic servlet未被错误配置,并且在不应该配置的时候允许多个线程。 (也许不应该将Peoplesoft代码与多个线程竞争。)

为什么会在一台特定的服务器上发生?

如果是负载均衡的,请考虑服务器是否由于其相对于Web服务用户的物理位置而承担了大部分负载。更多的活动将增加线程竞争的机会。


0
投票

夫妇:

我对要检查的内容没有足够的想法。

服务器硬件如何。是否有可能是服务器内存较少,CPU数量较少或较慢而导致负载不同的交互?

如果它从不在其他服务器上发生,则说明非常错误。您是否有办法将硬盘从工作中的服务器复制到损坏的服务器上?在我看来,这存在某种配置差异或某些差异。

另一个线程(我假设)在LinkedList上进行迭代,然后导致ConcurrentModificationException。

实际上,两个线程在相同的LinkedList上进行迭代是很好的。不好的是,如果在线程对其进行迭代时列表发生了变化。实际上,对于单线程应用程序来说,查看CME通常是more。在可能导致迭代抛出的情况下,线程可以从列表中删除某些内容。

作为一个hack,根据您的绝望程度,您可以在类路径上提供一个不同的LinkedList类并对其进行检测,甚至对其添加锁以了解甚至防御该问题。

© www.soinside.com 2019 - 2024. All rights reserved.