Oracle Service Bus –线程阻塞案例研究

本案例研究描述了在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 可以重载等于号码_Java面试之Java基础4——重载与重写的区别

目录重载与重写的概念重载与重写的区别重载与重写的总结构造器是否能被重写override为什么函数不能根据返回类型来区分重载重载与重写的概念重载&#xff1a;同样一个方法可以根据输入参数列表的不同&#xff0c;做出不同的处理。普通方法和构造器方法都能够重载。方法重载&…

二维数组、多维数组

二维数组&#xff1a; 定义二维数组 int[,] myArray new int[几个一维数组,数组中的个数]; 数组可以具有多个维度。例如&#xff0c;下列声明创建一个四行两列的二维数组(可以理解为4个1维数组&#xff0c;数组中包含2个元素)&#xff1a; int[,] myArray new int[4,2]; int[…

一张大图片有多个小图片

这个页面也是我看到别人的写的&#xff0c;感觉不错&#xff0c;就自己留下了为了以后自己可以容易找到&#xff0c;也希望可以方便到别人。 写这个页面 需要注意的是&#xff1a; 1.写每一个小图片的位置时候&#xff0c;要用id,这样等级就高了&#xff0c;不然不起作用。 2.因…

java中如何调用dal接口案例_关于Java:接口的目的

好吧&#xff0c;我认为接口是一种强制对象实现一定数量功能的方法&#xff0c;而不必使用继承。有点像合同。我半明白他们的意思。但是&#xff0c;如果界面中的所有内容都是&#xff1a;public interface animal{void eat(object food);}它没有这样的实现&#xff0c;那么无论…

Android Studio混淆

这一篇说一下Android Studio的代码混淆&#xff1a; 第一步&#xff1a;要想使混淆生效&#xff0c;要修改项目&#xff08;App&#xff09;下的build.gradle一处内容&#xff1a;minifyEnabled 的值 设置为true&#xff0c;当前项目就可以使用混淆了。 apply plugin: com.and…

内存访问模式很重要

在高性能计算中&#xff0c;通常会说高速缓存未命中的代价是算法的最大性能损失。 多年来&#xff0c;处理器速度的提高大大超过了延迟到主内存的速度。 通过更宽的多通道总线&#xff0c;到主内存的带宽已大大增加&#xff0c;但是延迟并未显着减少。 为了掩盖这种延迟&#x…

上传头像将光标去掉

οnfοcus"this.blur();" unselectable"on" οnfοcus"this.blur();"支持火狐&#xff0c;谷歌等主流浏览器 unselectable支持ie浏览器转载于:https://www.cnblogs.com/jar-gon/p/6841239.html

java底层 文件操作_JAVA的文件操作【转】

11.3 I/O类使用由于在IO操作中&#xff0c;需要使用的数据源有很多&#xff0c;作为一个IO技术的初学者&#xff0c;从读写文件开始学习IO技术是一个比较好的选择。因为文件是一种常见的数据源&#xff0c;而且读写文件也是程序员进行IO编程的一个基本能力。本章IO类的使用就从…

JAVA多线程,真的能提高效率吗

举个栗子 比如挖一个隧道&#xff0c;有2种开工方法1、只在山的一头挖&#xff0c;直至挖到山的另一头&#xff0c;从而打通隧道&#xff0c;这可以看成是单线程 2、在山的两头挖&#xff0c;同时开工&#xff0c;最后在山的中间接通&#xff0c;从而打通隧道&#xff0c;这感觉…

Java 8:测试Lambda水

Java 8大约有一年的时间了&#xff0c;它具有我非常期待的语言功能&#xff1a; Lambda Expression 。 令人遗憾的是&#xff0c;另一个重要功能Java平台模块已延迟到Java9。但是&#xff0c;将lambda表达式&#xff08;或闭包&#xff09;添加到该语言中将使Java编程变得更好。…

java定义js函数_JS中可以先使用函数,然后再定义.

首先要说明的,下面这种方式是对的,虽然不知道为什么,很奇怪为什么可以先使用,再定义,希望有了解的人可以给个说法.hello(www.openj.cn);function hello(name){alert("hello " name)};本文首发于 http://blog.openj.cn下面的这种定义函数方式,对于写一些比较复杂的代码…

基于阀值的工作流引擎设计

最近在做工作流处理流程部分的工作&#xff0c;顺便研究了一下工作流引擎的一些设计理念和原理。由于以前接触过人工智能神经网络的一些东西&#xff0c;发现工作流引擎和神经网络还是颇有一些相似之处&#xff0c;都是满足一定的条件下向下一个节点传递。在神经网络的神经元中…

Git之安装管理

1.Git安装部署 Git是分布式的版本控制系统&#xff0c;我们只要有了一个原始Git版本仓库&#xff0c;就可以让其他主机克隆走这个原始版本仓库&#xff0c;从而使得一个Git版本仓库可以被同时分布到不同的主机之上&#xff0c;并且每台主机的版本库都是一样的&#xff0c;没有主…

Java执行程序服务类型

ExecutorService功能是Java 5附带的。它扩展了Executor接口&#xff0c;并提供了线程池功能来执行异步简短任务。 使用Java 6提供的ExecutorService接口有五种异步执行任务的方法。 ExecutorService execService Executors.newCachedThreadPool&#xff08;&#xff09;; 这…

MySQL的主动优化和被动优化_MySQL“被动”性能优化汇总!

年少不知优化苦&#xff0c;遇坑方知优化难。 ——村口王大爷本文内容导图如下&#xff1a;我之前有很多文章都在讲性能优化的问题&#xff0c;比如下面这些&#xff1a;当然&#xff0c;本篇也是关于性能优化的&#xff0c;那性能优化就应该一把梭子吗&#xff1f;还是要符合一…

python2

一、管理库的安装 安装pip 提示报错&#xff1a;安装pip提示No module named setuptools Windows环境下Python默认是没有安装setuptools这个模块的&#xff0c;这也是一个第三方模块。下载地址为http://pypi.python.org/pypi/setuptools。下载后直接运行ez_setup.py 参考地址&…

Java Mybatis

Mybatis转载于:https://www.cnblogs.com/leading-index/p/6853031.html

Java例外:java lang NoSuchMethodError

如果查看错误消息java.lang.NoSuchMethodError&#xff0c;您可能会理解Java虚拟机正在尝试向我们表明您调用的方法在类或接口中不可用。 您还可能在执行没有公共static void main&#xff08;&#xff09;方法的类时抛出此错误。要了解其背后的原因&#xff0c;请阅读本文。 …

【图】最短路径——Floyed算法和Dijkstra算法

最短路径问题(floyed.cpp dijkstra.cpp) 题目描述平面上有n个点(n<100)&#xff0c;每个点的坐标均在-10000&#xff5e;10000之间。其中的一些点之间有连线。若有连线&#xff0c;则表示可从一个点到达另一个点&#xff0c;即两点间有通路&#xff0c;通路的距离为两点间的…

java的empty_Java Stack empty()方法与示例

堆栈类empty()方法empty()方法在java.util包中可用。empty()方法用于检查此堆栈是否为空。empty()方法是一个非静态方法&#xff0c;只能通过类对象访问&#xff0c;如果尝试使用类名称访问该方法&#xff0c;则会收到错误消息。在检查空状态时&#xff0c;empty()方法不会引发…