背景

如今容器化大行其道,不懂点docker都不好意思跟人打招呼,但容器化后也给运维带来了很大的挑战,容器都讲究小而精,尽可能在最小的体积里运行应用,减少体积的结果就是要舍弃一些工具,比如ping,大部分容器都舍弃了该工具,导致在容器里需要获取一个host的ip变得麻烦很多。java应用也一样,有可能容器中就只有一个java其他什么都没有,在这种情况下如何进行问题的诊断,如何使用java诊断神器arthas。

卷挂载方式

由于Arthas免安装,只是一些jar包,所以可以在docker运行时通过卷的方式挂载到容器内部。以tomcat为例

docker run -p 8888:8080 -v /you/path/arthas-packaging-3.1.7-bin/:/arthas -d tomcat

在运行时将arthas相关jar包目录挂载到容器内/arthas目录下,进入容器环境启动arthas

Read the rest of this entry

背景

在开发bpm流程,流程流转到平行审批节点时报错,流程如下:

报错信息如下:

Caused By: java.lang.NullPointerException
        at oracle.bpm.bpmn.engine.model.runtime.microinstructions.MIUserTaskRequest.addTaskAttributesToXml(MIUserTaskRequest.java:568)
        at oracle.bpm.bpmn.engine.model.runtime.microinstructions.MIUserTaskRequest.processInputData(MIUserTaskRequest.java:319)
        at oracle.bpm.bpmn.engine.model.runtime.microinstructions.MIUserTaskRequest.handleTaskServiceInvoke(MIUserTaskRequest.java:158)
        at oracle.bpm.bpmn.engine.model.runtime.microinstructions.MIUserTaskRequest.doExecute(MIUserTaskRequest.java:128)
        at oracle.bpm.bpmn.engine.microkernel.MIBase.execute(MIBase.java:34)
        at oracle.bpm.bpmn.engine.microkernel.MISequenceBlock.doExecute(MISequenceBlock.java:68)
        at oracle.bpm.bpmn.engine.microkernel.MIBase.execute(MIBase.java:34)
        at oracle.bpm.bpmn.engine.microkernel.MicroInstructionContext.callMicroInstruction(MicroInstructionContext.java:203)
        at oracle.bpm.bpmn.engine.microkernel.MICall.doExecute(MICall.java:38)
        at oracle.bpm.bpmn.engine.microkernel.MIBase.execute(MIBase.java:34)
        at oracle.bpm.bpmn.engine.microkernel.MISequenceBlock.doExecute(MISequenceBlock.java:68)
        at oracle.bpm.bpmn.engine.microkernel.MIBase.execute(MIBase.java:34)
        at oracle.bpm.bpmn.engine.microkernel.MicroInstructionContext.callMicroInstruction(MicroInstructionContext.java:203)
        at oracle.bpm.bpmn.engine.microkernel.MicroInstructionContext.callProcedure(MicroInstructionContext.java:210)
.......

Read the rest of this entry

背景

你是否和我一样一直有个疑问,如何查看系统执行过的所有sql,之前做oracle中间件实施的时候,由于oracle产品不开放源代码,也不公开表结构设计,因此一个功能涉及到哪些表,具体表里存的数据代表什么除了oracle没人知道,如果了解哪些功能涉及到哪些表,表里的数据都分表对应哪些功能更有助于我们对产品的理解和对问题的解决。

之前曾经想过通过oracle系统表v$sql进行监控,但效果并不理想,如果用过druid连接池应该知道,druid主打的功能就是sql监控(一个数据库连接池竟然干监控的活,有点不务正业),druid的原理是提供了一套jdbc的接口,自然所有的sql都要通过它来执行,这个也给了我们一个思路,如果可以监控jdbc相关方法的执行,不就可以实现以上目的,有了arthas之后,这个事就变得很简单。

jdbc

我们知道,jdbc中负责执行sql的是PreparedStatementStatement,PreparedStatement用于参数绑定,有防注入,避免硬解析等好处,Statement执行纯sql,因此正式环境一般推荐使用PreparedStatement进行sql操作,PreparedStatement通过Connection.prepareStatement(String sql)方法创建,所以我们监控该方法就能得到sql,arthas中watch命令可以监控方法的执行,那问题来了,Connection只是jdbc的接口,并非最终的实现类,我们需要监控的是实现类,并非接口,通过查看oracle jdbc驱动包不难发现,oracle jdbc对于Connection的实现类是oracle.jdbc.OracleConnectionWrapper,执行下面命令开始监控。

Read the rest of this entry

背景

今天开始新的系列,这个系列也是我一直想写的,有几个原因迟迟没开始,一个是担心自己学艺不精,误人子弟,另一个是没有积累较多的使用案例,目前这两个问题已经不是问题,arthas大部分命令也都使用过,并且也积累了较多案例,是时候开始动笔。

要写什么内容,这个也是我一直思考的问题,官网的文档已经很详细,我觉得没有必要再写一份介绍如何使用的教程,arthas的魅力在于线上调试java的黑科技,这一点官网的几个简单示例是不足以展现的,因此我绝对本系列着重讲实战,通过具体的例子展现arthas神奇的黑科技。

既然要写实战,那为什么还要写入门篇,入门是让你知道arthas是个什么东西,怎么安装,知道这两点就够了,足以让你学习接下来的内容,入门还是很有必要的,就像你追一个妹子,再喜欢也要先了解对方的基本信息,投其所好,磨刀不误砍柴工。

Read the rest of this entry