本案例研究描述了在AIX 6.1和IBM Java VM 1.6上运行的Oracle Service Bus 11g遇到的线程阻塞问题的完整根本原因分析过程。
本文也是您提高线程转储分析技能的绝佳机会,我强烈建议您学习并正确理解以下分析方法。 与过早的中间件(Weblogic)重新启动相比,它还将证明正确收集数据的重要性。

环境规格

  • Java EE服务器:Oracle Service Bus 11g
  • 操作系统:AIX 6.1
  • JDK:IBM JRE 1.6.0 @ 64位
  • RDBMS:Oracle 10g
  • 平台类型:企业服务总线

故障排除工具

  • Quest Software Foglight for Java(监视和警报)
  • Java VM线程转储(IBM JRE javacore格式)

问题概述
 
从我们的Oracle Service Bus Weblogic环境中观察到主要性能下降。 Foglight代理还发送了警报,表明Weblogic线程使用率显着增加。

事实的收集和验证
 
像往常一样,Java EE问题调查需要收集技术事实和非技术事实,因此我们可以得出其他事实和/或就根本原因进行结论。 在采取纠正措施之前,要对以下事实进行核实,以便得出根本原因:

  • 对客户有什么影响? 高
  • 受影响平台的最近更改? 是的,在中断报告之前,OSB控制台中的一些业务服务的日志记录级别已更改
  • 受影响平台最近的流量增加了吗? 没有
  • 自从多久以来观察到此问题? 日志记录级别更改后观察到新问题
  • 重新启动Weblogic服务器是否可以解决问题? 是

结论1 :先前在某些OSB商业服务上应用的日志记录级别更改似乎触发了此线程阻塞问题。 但是,此时的根本原因仍然未知。

Weblogic线程监视:Java的Foglight
 
Foglight for Java (来自Quest Software)是一款出色的监视工具,可让您完全监视任何Java EE环境以及完整的警报功能。 在我们的生产环境中使用此工具来监视每个Oracle Service Bus受管服务器的中间件(Weblogic)数据,包括线程。 您可以在下面看到线程的持续增加以及未决的请求队列。

供您参考,Weblogic运行缓慢的线程被标识为“正在运行的线程”,并且如果运行几分钟(根据您配置的阈值),最终可以提升为“ STUCK”状态。

现在,您下一步应该采取什么行动? Weblogic重新启动? 绝对不是……针对此类问题的第一个“反应”是捕获JVM线程转储。 此类数据对于您执行正确的根本原因分析并了解潜在的悬挂状况至关重要。 捕获到此类数据后,您就可以继续执行Weblogic服务器恢复操作,例如重新启动完全托管服务器(JVM)。

卡住的线程:线程转储可以进行救援!
 
此中断场景中的下一个操作步骤是,在尝试恢复受影响的Weblogic实例之前,从IBM JVM快速生成一些线程转储快照。 线程转储是使用kill -3 <Java PID>生成的,它确实在Weblogic域的根目录生成了一些javacore文件。

javacore.20120610.122028.15149052.0001.txt

一旦生产环境备份并开始运行,团队将按照以下步骤Swift进行捕获的线程转储文件的分析。

线程转储分析步骤1 –确定线程执行模式
 
第一步分析是快速遍历所有Weblogic线程,并尝试确定常见的问题模式,例如从远程外部系统等待的线程,处于死锁状态的线程,从其他线程等待以完成其任务的线程等。

该分析确实Swift揭示出许多线程与以下相同的阻塞情况有关。 在此示例中,我们可以在TransactionManager Java类(OSB内核代码)中看到处于阻塞状态的Oracle Service Bus线程。

[ACTIVE] ExecuteThread: '292' for queue: 'weblogic.kernel.Default (self-tuning)'"J9VMThread:0x0000000139B76B00, j9thread_t:0x000000013971C9A0,java/lang/Thread:0x07000000F9D80630, state:B, prio=5(native thread ID:0x2C700D1, native priority:0x5, native policy:UNKNOWN)Java callstack:at com/bea/wli/config/transaction/TransactionManager._beginTransaction(TransactionManager.java:547(Compiled Code))at com/bea/wli/config/transaction/TransactionManager.beginTransaction(TransactionManager.java:409(Compiled Code))at com/bea/wli/config/derivedcache/DerivedResourceManager.getDerivedValueInfo(DerivedResourceManager.java:339(Compiled Code))at com/bea/wli/config/derivedcache/DerivedResourceManager.get(DerivedResourceManager.java:386(Compiled Code))at com/bea/wli/sb/resources/cache/DefaultDerivedTypeDef.getDerivedValue(DefaultDerivedTypeDef.java:106(Compiled Code))at com/bea/wli/sb/pipeline/RouterRuntimeCache.getRuntime(RouterRuntimeCache.java(Compiled Code))at com/bea/wli/sb/pipeline/RouterManager.getRouterRuntime(RouterManager.java:640(Compiled Code))at com/bea/wli/sb/pipeline/RouterContext.getInstance(RouterContext.java:172(Compiled Code))at com/bea/wli/sb/pipeline/RouterManager.processMessage(RouterManager.java:579(Compiled Code))at com/bea/wli/sb/transports/TransportManagerImpl.receiveMessage(TransportManagerImpl.java:375(Compiled Code))at com/bea/wli/sb/transports/local/LocalMessageContext$1.run(LocalMessageContext.java:179(Compiled Code))at weblogic/security/acl/internal/AuthenticatedSubject.doAs(AuthenticatedSubject.java:363(Compiled Code))at weblogic/security/service/SecurityManager.runAs(SecurityManager.java:146(Compiled Code))at weblogic/security/Security.runAs(Security.java:61(Compiled Code))at com/bea/wli/sb/transports/local/LocalMessageContext.send(LocalMessageContext.java:144(Compiled Code))at com/bea/wli/sb/transports/local/LocalTransportProvider.sendMessageAsync(LocalTransportProvider.java:322(Compiled Code))at sun/reflect/GeneratedMethodAccessor980.invoke(Bytecode PC:58(Compiled Code))at sun/reflect/DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37(Compiled Code))at java/lang/reflect/Method.invoke(Method.java:589(Compiled Code))at com/bea/wli/sb/transports/Util$1.invoke(Util.java:83(Compiled Code))at $Proxy111.sendMessageAsync(Bytecode PC:26(Compiled Code))
……………………………

线程转储分析步骤2 –检查被阻塞的线程链
 
下一步是检查涉及我们确定的模式的受影响和受阻的线程链。 正如我们在线程转储分析第4部分中看到的那样,IBM JVM线程转储格式包含一个单独的部分,该部分提供了所有线程阻塞链的完整细分,例如Java对象监视器池锁。

快速分析确实揭示了以下线程元凶。 如您所见,Weblogic线程#16是实际的罪魁祸首,有300多个线程正在等待获取共享库监视器TransactionManager @ 0x0700000001A51610 / 0x0700000001A51628上的锁。

2LKMONINUSE      sys_mon_t:0x000000012CCE2688 infl_mon_t: 0x000000012CCE26C8:
3LKMONOBJECT       com/bea/wli/config/transaction/TransactionManager@0x0700000001A51610/0x0700000001A51628: Flat locked by "[ACTIVE] ExecuteThread: '16' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000012CA3C800), entry count 1
3LKWAITERQ            Waiting to enter:
3LKWAITER                "[STUCK] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000011C785C00)
3LKWAITER                "[STUCK] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000011CA93200)
3LKWAITER                "[STUCK] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000011B3F2B00)
3LKWAITER                "[STUCK] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000011619B300)
3LKWAITER                "[STUCK] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000012CBE8000)
3LKWAITER                "[STUCK] ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'" (0x000000012BE91200)
..................

线程转储分析步骤#3 –线程元凶更深入的分析
 
一旦确定了罪魁祸首,下一步就是对该线程当前正在执行的计算任务进行更深入的审查。 只需返回原始线程转储数据,并从下至上开始分析罪魁祸首线程堆栈跟踪。

正如您在下面看到的那样,针对我们的问题案例的线程堆栈跟踪非常清楚。 它确实显示线程#16当前正在尝试提交在Weblogic / Oracle Service Bus级别进行的更改。 问题在于,提交操作正在挂起并且花费了太多时间,导致线程#16将来自TransactionManager的共享对象监视器锁定保留太长时间,并使其他Oracle Service Bus Weblogic线程“饥饿”。

"[ACTIVE] ExecuteThread: '16' for queue: 'weblogic.kernel.Default (self-tuning)'"
J9VMThread:0x000000012CA3C800, j9thread_t:0x000000012C9F0F40, java/lang/Thread:0x0700000026FCE120, state:P, prio=5
(native thread ID:0x35B0097, native priority:0x5, native policy:UNKNOWN)Java callstack:at sun/misc/Unsafe.park(Native Method)at java/util/concurrent/locks/LockSupport.park(LockSupport.java:184(Compiled Code))at java/util/concurrent/locks/AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:822)at java/util/concurrent/locks/AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:853(Compiled Code))at java/util/concurrent/locks/AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1189(Compiled Code))at java/util/concurrent/locks/ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:911(Compiled Code))at com/bea/wli/config/derivedcache/DerivedCache$Purger.changesCommitted(DerivedCache.java:80)at com/bea/wli/config/impl/ResourceListenerNotifier.afterEnd(ResourceListenerNotifier.java:120)at com/bea/wli/config/transaction/TransactionListenerWrapper.afterEnd(TransactionListenerWrapper.java:90)at com/bea/wli/config/transaction/TransactionManager.notifyAfterEnd(TransactionManager.java:1154(Compiled Code))at com/bea/wli/config/transaction/TransactionManager.commit(TransactionManager.java:1519(Compiled Code))at com/bea/wli/config/transaction/TransactionManager._endTransaction(TransactionManager.java:842(Compiled Code))at com/bea/wli/config/transaction/TransactionManager.endTransaction(TransactionManager.java:783(Compiled Code))at com/bea/wli/config/deployment/server/ServerDeploymentReceiver$2.run(ServerDeploymentReceiver.java:275)at weblogic/security/acl/internal/AuthenticatedSubject.doAs(AuthenticatedSubject.java:321(Compiled Code))at weblogic/security/service/SecurityManager.runAs(SecurityManager.java:120(Compiled Code))at com/bea/wli/config/deployment/server/ServerDeploymentReceiver.commit(ServerDeploymentReceiver.java:260)at weblogic/deploy/service/internal/targetserver/DeploymentReceiverCallbackDeliverer.doCommitCallback(DeploymentReceiverCallbackDeliverer.java:195)at weblogic/deploy/service/internal/targetserver/DeploymentReceiverCallbackDeliverer.access$100(DeploymentReceiverCallbackDeliverer.java:13)at weblogic/deploy/service/internal/targetserver/DeploymentReceiverCallbackDeliverer$2.run(DeploymentReceiverCallbackDeliverer.java:68)at weblogic/work/SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528(Compiled Code))at weblogic/work/ExecuteThread.execute(ExecuteThread.java:203(Compiled Code))at weblogic/work/ExecuteThread.run(ExecuteThread.java:171(Compiled Code))

根本原因:连接点
 
在这一点上,事实和线程转储分析的收集确实使我们能够确定事件链如下:

  • 生产Oracle Service Bus管理员应用的日志记录级别更改
  • Weblogic部署线程#16无法正确提交更改
  • 快速执行客户端请求的Weblogic运行时线程开始排队并等待共享对象监视器(TransactionManager)上的锁定
  • Weblogic实例的线程不足,生成警报并迫使生产支持团队关闭并重新启动受影响的JVM进程

我们的团队计划不久后开放一个Oracle SR,以共享此OSB部署行为以及客户端请求(线程)和OSB日志记录层之间的硬依赖性。 在此期间,除非另行通知,否则不会在维护时段内尝试更改OSB日志记录级别。

结论
 
我希望本文能帮助您理解和理解强大的线程转储分析功能,以查明线程阻塞问题的根本原因,以及任何Java EE生产支持团队捕获此类重要数据以防止将来再次发生的重要性。 请不要犹豫,发表任何评论或问题。

参考: Oracle服务总线–我们JCG合作伙伴 Pierre-Hugues Charbonneau的“ 阻塞线程”案例研究 ,位于Java EE支持模式和Java教程博客。

翻译自: https://www.javacodegeeks.com/2012/08/oracle-service-bus-stuck-thread-case.html

Oracle Service Bus –线程阻塞案例研究相关推荐

  1. oracle线程阻塞_Oracle Service Bus –线程阻塞案例研究

    oracle线程阻塞 本案例研究描述了在AIX 6.1和IBM Java VM 1.6上运行的Oracle Service Bus 11g遇到的线程阻塞问题的完整根本原因分析过程. 本文也是您提高线程 ...

  2. Oracle Service Bus简介

    我们正在为电信提供商设计一个新系统,在该系统中,我们研究了用作企业服务总线的Oracle服务总线(OSB). 对我来说,第一个优点是它提供了惊人的工具支持. 通过将其捆绑为Oracle SOA套件,O ...

  3. OSB集成平台项目-回顾 (Oracle service bus)

    甲方项目经理详细讲述整个项目的历程,内中包含大量企业级ESB的技术细节,抛砖引玉供大家分享. 金康汽车数据集成平台项目从2018年6月15日项目启动,通过项目组近6个月的努力,于2018年12月28日 ...

  4. java线程死锁_Java线程死锁–案例研究

    java线程死锁 本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析. 此案例研究还将证明掌握线程转储分析技能的重要性: 包括 ...

  5. Log4j线程死锁–案例研究

    此案例研究描述了影响Weblogic Portal 10.0生产环境的Apache Log4j线程争用问题的完整根本原因分析和解决方案. 它还将说明在开发和支持Java EE应用程序时适当的Java类 ...

  6. Java线程死锁–案例研究

    本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析. 此案例研究还将证明掌握线程转储分析技能的重要性: 包括用于IBM JVM ...

  7. 数据集成平台的特点(Oracle service bus)

    时间过得很快,ESB(数据集成平台)项目本月就要上线,之后转入运维. 现在总结一下,数据集成平台有以下特点: 1.高效稳定的消息处理 2.简单易用的数据管理 3.接口服务整体企业架构高可用 4.多协议 ...

  8. osgi 模块化_OSGi案例研究:模块化vert.x

    osgi 模块化 OSGi使Java代码可以清晰地划分为多个模块,这些模块称为捆绑软件 ,可以访问由每个捆绑软件的类加载器控制的代码和资源. OSGi 服务提供了一种附加的分离机制:接口的用户无需依赖 ...

  9. OSGi案例研究:模块化vert.x

    OSGi使Java代码可以清晰地划分为多个模块,这些模块称为捆绑软件 ,可以访问由每个捆绑软件的类加载器控制的代码和资源. OSGi 服务提供了一种附加的分离机制:接口的用户不需要依赖于实现类,工厂等 ...

最新文章

  1. html单击按钮时弹出输入框,点击按钮弹出模态框的一系列操作代码实例
  2. 【问链财经-区块链基础知识系列】 第三十二课 从区块链溯源来看农产品链的设计
  3. 有种欢迎叫“来了就是深圳人”
  4. HDU - 4507 吉哥系列故事——恨7不成妻(数位dp)
  5. 简单的java方法_Java简单实用方法一
  6. python 示例_Python TextCalendar类别| pryear()方法与示例
  7. jq判断是否为整数_五种js判断是否为整数(转)
  8. [RL] 配置 gym 与 atari 游戏
  9. HTML5+CSS3从入门到精通
  10. 〖Python APP 自动化测试实战篇④〗- 通过 appium 驱动夜神模拟器完成第一个自动化脚本 - 查看通讯录
  11. 大数据服务节点配置参考
  12. Win11系统svchost.exe一直在下载怎么办?
  13. fixed在ios失效解决方案
  14. 编程环境和软件工具安装手册
  15. 团体程序设计天梯赛-练习集)(5分)
  16. linux系统ubuntu
  17. Coursera | Andrew Ng (02-week-1-1.7)—理解 Dropout
  18. Cython入门:将python代码转为cython
  19. hardware 中的几个地址问题
  20. Spring Cloud(十四):微服务灰度发布 --- Discovery

热门文章

  1. jvm 启动参数设置
  2. 如何在linq使用左连接
  3. java从数组查找指定整数_如何在Java中使用重复项查找整数数组中的K个缺失数字?...
  4. envoy重试_具有Envoy代理的微服务模式,第二部分:超时和重试
  5. 面向对象代码_面向对象的代码生成方法
  6. jdk8分组统计字段和_JDK 8流和分组
  7. Angular 8 + Spring Boot 2.2:立即构建一个CRUD应用程序!
  8. Spring@懒惰注释
  9. 带有AngularJS资源的Spring Rest Controller
  10. java开发人员_Java 8:开发人员怎么看?