问题描述:

在一个在线运行的java web系统中,会定时运行一个FTP上传的任务,结果有一天发现,文件正常生成后却没有上传。

问题初步分析:

1.查看日志文件

发现这个任务只打印了开始进入FTP处理的日志,但是没有打印FTP处理完成的日志。

从代码上看,FTP上传处理的代码异常保护都非常的好,如果出现异常,就会进行打印,而日志文件中却没有相关的信息,甚是奇怪。怀疑是FTP过程问题,如对方FTP服务器有什么问题导致,但是却找不到证据。

苦于无法窥探java运行系统内部信息,祭出杀手锏-jstack。

2.通过jstack分析

在运行系统上,通过jps命令(也可以通过其他方式,如ps)查看运行中的java程序的进程ID,使用jstack
pid > jstack.log 将线程堆栈信息导出到jstack.log文件中,找到如下有用的信息。

通过代码确认,下方的UploadFtpTask确实就是我们的文件上传任务的执行代码。

通过堆栈信息看,线程状态为RUNNABLE,不是BLOCKED状态,说明不是因为锁导致线程阻塞,而是阻塞在了网络读取上。

<span style="font-size:14px;">"DefaultQuartzScheduler_Worker-5" prio=10 tid=0x00002aaaf4382801 nid=0x1874 runnable [0x000000004133b000..0x000000004133bda0]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
- locked <0x00002aaac3cdd061> (a java.io.InputStreamReader)
at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)
- locked <0x00002aaac3cdd061> (a java.io.InputStreamReader)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)
at java.io.InputStreamReader.read(InputStreamReader.java:151)
at it.sauronsoftware.ftp4j.NVTASCIIReader.readLine(NVTASCIIReader.java:105)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.read(FTPCommunicationChannel.java:142)
at it.sauronsoftware.ftp4j.FTPCommunicationChannel.readFTPReply(FTPCommunicationChannel.java:187)
at it.sauronsoftware.ftp4j.FTPClient.connect(FTPClient.java:1034)
- locked <0x00002aaac3cdd109> (a java.lang.Object)
at com.xx.FtpClientImpl.connect(FtpClientImpl.java:56)
at com.xx.UploadFtpTask.execute(UploadFtpTask.java:88)
at org.quartz.core.JobRunShell.run(JobRunShell.java:216)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)</span>

通过引用的jar包确认,这个FTP功能使用的开源包ftp4j来实现的,使用的版本为1.5.1。

写个测试程序,看看FTP连接时的调用堆栈:

Socket.connect(SocketAddress) line: 469 

Socket.<init>(SocketAddress, SocketAddress, boolean) line: 366 

Socket.<init>(String, int) line: 180 

DirectConnector.connect(String, int) line: 35 

DirectConnector.connectForCommunicationChannel(String, int) line: 40 

FTPClient.connect(String, int) line: 1024 

FTPClient.connect(String) line: 991 

Test.main(String[]) line: 19

而Socket 的469行是什么呢?

connect(endpoint, 0);

这个函数的定义为:public void connect(SocketAddress endpoint, int timeout)  ,上面的调用相当于设置了timeout为0,那就意味着出现网络丢包或者对端服务有问题时,这个连接会无限制等待下去。这就杯具了。

再看看这个开源项目后续是否对此问题做过修改呢?下载1.7.2版本,再次测试,查看调用堆栈:

Socket.connect(SocketAddress, int) line: 490 

DirectConnector(FTPConnector).tcpConnectForCommunicationChannel(String, int) line: 208 

DirectConnector.connectForCommunicationChannel(String, int) line: 39 

FTPClient.connect(String, int) line: 1036 

FTPClient.connect(String) line: 1003 

Test.main(String[]) line: 19

通过tcpConnectForCommunicationChannel去调用Socket的connect方法时,传入了超时时间,为10秒(10*1000)。这就引入了超时机制,如果出现上面问题时,就不会死等了。

总结:

1.jstack工具是定位在线运行java系统的利器,可以查看线程堆栈信息,这对于分析问题非常重要,特别是在日志分析和代码分析无法确定问题时。

2.网络连接时,必须设置超时,不能无限制等待。发散一下,开发系统时,必须考虑各种异常情况。套用那句话,出来混,总是要还的。

转载请注明出处:http://blog.csdn.net/u014569459/article/details/38542949




通过jstack定位在线运行java系统故障_案例1的更多相关文章

  1. 通过jstack定位在线执行java系统故障_案例1

    问题描写叙述: 在一个在线执行的java web系统中,会定时执行一个FTP上传的任务,结果有一天发现,文件正常生成后却没有上传. 问题初步分析: 1.查看日志文件 发现这个任务仅仅打印了開始进入FT ...

  2. 利用btrace工具监控在线运行java程序

     一.作用 可以用于对运行中java程序进行诊断监控分析,也可以用于开发阶段查看一些异常信息或者调用过程(如有些第三方代码没有源代码,不便于debug调试). 注:如果用于对在线运行系统的诊断,需 ...

  3. 无IDE时编译和运行Java

    最近 Java subreddit 出现了一篇”在没有IDE的情况下编译Java包” 的帖子,这个帖子抛出了这么一个问题,“是否存在一个命令可以编译一组处于同一文件夹下独立包内的java文件的方法(这 ...

  4. java开发_模仿百度文库_OpenOffice2PDF_注意事项

    在模仿百度文库的操作过程中,有很多朋友反映出来的一些问题,是我想起了写这篇blog. 主要是让大家在做的过程中注意一些东西,否则达不到想要的效果. 第一步:我们先从 java开发_模仿百度文库_Ope ...

  5. 如何使用命令行编译以及运行java文件

    要想编译和运行java文件,很简单,只需要两个命令: (1) javac:作用:编译java文件:使用方法: javac Hello.java ,如果不出错的话,在与Hello.java 同一目录下会 ...

  6. [JAVA] 一个可以编辑、编译、运行Java简单文件的记事本java实现

    本来是Java课做一个仿windows记事本的实验,后来突然脑子一热,结果就给它加了一个编译运行Java文件的功能. 本工程总共大约3000行代码,基本上把所学的java界面.文件.控件的功能都包含在 ...

  7. Java魔法堂:以Windows服务的形式运行Java程序

    一.前言 由于防止维护人员误操作关闭Java控制台程序,因此决定将其改造为以Windows服务的形式运行.弄了一个上午总算搞定了,下面记录下来,以供日后查阅. 二.Java Service Wrapp ...

  8. [转]无IDE时编译和运行Java

    本文由 ImportNew - Grey 翻译自 dzone.欢迎加入Java小组.转载请参见文章末尾的要求. 最近 Java subreddit 出现了一篇”在没有IDE的情况下编译Java包” 的 ...

  9. Java核心_内省

    Java核心_内省 查看java的api,发现有一个包java.bean咦,这个包是干什么的呢,原来,它是用来操作JavaBean对象的! 一.内省操作①JavaBean:一种特殊的Java类无参构造 ...

随机推荐

  1. 【转】如何调整visio绘图区域尺寸大小

    原文网址:http://jingyan.baidu.com/article/948f5924033870d80ff5f9f1.html 在使用microsoft visio软件绘图时,为了绘图的质量和 ...

  2. Hadoop开发遇到的问题之reduce卡住

    遇到的问题描述:在hadoop上面执行程序,程序运行之后能够正常执行.一切似乎都是正常的,然而过了一段时间之后程序便开始阻塞直到程序超时退出(如下). 14/08/19 21:17:51 INFO m ...

  3. day55

    担心了好久的编译原理也总是考完了 大学里的最后一次考试也是结束罗 这次的考试起伏跌宕啊 我们本来是9点钟开始考试 但是我们班的几个同学基本上7点钟就去了 为了什么?? 选个好的位置撒哈哈,到了九点,老 ...

  4. Bootstrap--本地安装使用

    1.到官网下载:http://v2.bootcss.com 2.下载后是一个压缩文件,把它放在相应的工作目录下,然后解压. 3.新建一个测试文件,然后导入两个文件.

  5. android studio 开发android app 真机调试

    大家都知道开发android app 的时候可以有2种调试方式, 一种是Android Virtual Device(虚拟模拟器) ,另一种就是真机调试. 这里要说的是真机调试的一些安装步骤: 1. ...

  6. thinking in java知识小记(一)

    知识点一(javadoc): 使用javadoc时特别注意选择encoding和charset为utf-8,要不然生成的javadoc会是乱码,命令:javadoc -encoding utf-8 - ...

  7. .NET基础拾遗(4)委托为何而生?

    生活中的例子: 你早上要吃包子作为早饭,那么你可能让你爸爸或者妈妈帮你做,那你就会调用 爸爸.要包子() 或妈妈.要包子() 返回包子对象. 但是如果你爸妈不在家的时候,你只能去街上买,问题是你根本不 ...

  8. Jquery:Jquery中的事件<一>

    由于今天有一个比较重要的面试,所以昨天晚上对以前做的一些项目做了一下总结,直接导致昨天的学习笔记断更了,哎,计划永远赶不上变化啊!今天学习了Jquery中是事件,就此做一个笔记,便于日后复习. 一.加 ...

  9. PowerDesigner与UML建模应用

    一.   PD简介 PowerDesigner 是一个集所有现代建模技术于一身的完整工具,它集成了强有力的业务建模技术.传统的数据库分析和实现,以及UML对象建模.通过了元数据的管理.冲突分析和真正的 ...

  10. linux环境下jdk 安装以及maven私服搭建

    1:准备资源      linux服务器,jdk和nexus  安装包    2:网络通畅,保持windows端和linux服务器端网络通畅.     3: 安装jdk和配置环境变量      进入到 ...