首页 > 代码库 > 批量线程阻塞
批量线程阻塞
17在3月6号有失败情况。
19,20都停了。10,2也都停了。
2017年3月17日00:29:32
分析可能是BatchRunner类里的monitor崩溃了。
现象是:批量机的调度程序,是正常的,并且一直到时启动。但是批量并未执行。而非批量机却由于有core的日切调用,会有一条数据。(隔一天有一条,是由于负载的原因)
猜想是runBatch在执行17的队列时,遇到某种错误,导致线程挂掉了。但是runBatch又捕捉了Throwable,理论上来说,所有异常错误都会捕捉到的。
或者runBatch没有发生错误,而是一直被阻塞了。如果是这样的话,也可以解释出现的现象
17的批量,第一步显示的状态是运行中,后面的几步都是待运行。
需要检查下,数据是否有锁表。(但是如果有锁表,为什么另一台机器有成功数据呢?有没有可能是在单机事务里有锁冲突?)
估计能确认是哪里的问题了。但是原因不清楚
HttpClientImpl里 if (200 == connection.getResponseCode()) 这个地方发生阻塞。导致线程一直阻塞,而pay的批量又是顺序执行的。在WorkStep里ExecutorService executor = Executors.newCachedThreadPool();看到这个方法
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
这个用的是同步队列,只会一个一个的执行,并且执行完一个才执行下一个。所以线程阻塞后,虽然quarz一直在送内容过来,但是得不到执行。(http://blog.csdn.net/zbd_answer/article/details/20630719?locationNum=13)
这和所有的现象是吻合的。
现象:
1、批量机thread-420线程,在执行17队列的1701step时,发生阻塞,然后后边再也没有thread-420的线程,以及其他类似线程。
2、quart的线程一直都有执行。
3、非批量机的10队列是可以执行的。(core日切的时候会通知pay,core访问pay的时候,是通过负载访问的,目前的策略是访问批量机一天,访问非批量机一天)
4、很多地方都是对throwable进行的捕捉,所以如果线程崩溃的话,一定会有日志的。但是日志里没有相关信息
5、批量机的thread-420线程,通过pstack命令,显示的堆栈信息(并不是熟悉的开发的堆栈信息,而是很抽象的信息)是在socketinputstream_socketread 说明是仍然在等待读取。用netstat 查询8091端口(访问银联时,代理服务器的端口)发现一直有一个连接(established),而17号并无交易发生。
为了对比,对非批量机的批量线程进行了同样操作,pstack显示非批量机的线程是在进行timewait。而查询8091端口,则没有连接,然后做银联的交易,再次查询8091端口,出现了连接,稍后,再次查询,连接消失,说明连接会自己关闭的,由此更能印证批量机一定是阻塞了,所以连接一直不关闭
之前曾经怀疑的几个点:
1、数据库发生锁了?但是非批量机可以执行10批量,所以不会是数据库的锁造成的
2、quartz线程崩溃了?但是批量机的日志里是有此线程的日志信息的。
3、批量线程崩溃了?最开始也认定是这个,但是仔细分析,由于捕捉了throwable,但是又没有日志很奇怪。另外发现批量机里有thread-420的线程。当然我并不能百分百认定这个thread-420线程就是批量线程。但是通过其他信息辅助,有很大把握相信这个就是批量线程
4、执行批量的时候是有事务的,是不是两个线程的事务有冲突了?这个并未验证到这里,首先部分现象不支持这个猜想。另外线程阻塞这个猜想,我认为非常有可能是这个。
原因:
那么,到底是什么原因造成线程阻塞了呢?
不知道,网上都说是由于没有设置readtimeout,但是很明显,我们设置这个参数了。
http://www.4byte.cn/question/788682/httpurlconnection-getresponsecode-freezes-execution-doesn-t-time-out.html
这篇文章也提到设置readtimeout了,但是线程也被freezes了(HttpURLConnection.getResponseCode() freezes execution/doesn‘t time out)
不过,并没有人给出原因
具体原因,仍然有待调查
接下来要做的验证:
本地执行一个17的队列,跟踪一下每一步,数据库的变化,以及workstep是否是我想的那样。(看用意,用线程池执行应该异步才合理,但是线程池是排队执行的,并且是同步的。2017年3月18日13:41:04 也有可能设计者是想重复利用线程,以规避线程的开销?)
在生产代理服务器上,查一下批量机的本地端口,如果代理服务器上有,说明双方之间有连接,如果代理服务器上没有,说明连接丢失?
查了,代理服务器上,并没有批量机的连接
在31批量机的websphere的控制台,打堆转储,java核心(执行5次,每次隔30秒),系统转储
如果仍未能找到原因,需要打更丰富的日志,以及目前猜测原因的辅助日志
鉴于这种情况,需要对批量机制加心跳机制。
2017年3月28日
对比生产war包的问题的时候,发现31pay的银联的transport.xml里没有connectiontimeout和readtimeout参数真的没有。经查,是压包工程将改动覆盖了。
批量线程阻塞