双11前来三个case的分享

最近堪称问题爆发的高发期,不过有不少是重复的cases,挑三个分享下。

Case I
有个应用cpu sy消耗很高,现象是线程数太多,但现场已经没有了,在出现问题的时候有做过线程的dump和内存dump,从线程dump看到的就是大量的线程池的线程在等待,但最郁闷的又是没有名字的线程池,于是无法从这个堆栈看出来到底是什么地方造成的,对这种问题,最好的办法是有现场,然后直接btrace跟踪下是哪个地方在不断的创建线程。

既然没有现场,就尝试拿着内存dump分析下,看了那些创建的N多的线程,从中发现了一个点,就是线程的线程组名,从这个线程组名上对应到了代码的名字,根据这个知道了是哪个地方造成的问题。

这个后来查到的原因是一个类里每次会new ThreadPoolExecutor,原因是开发有些误解,以为这个类只会new一次,这种理解上的问题很容易导致一些超出预期的运行状况,不过对于线程池,我始终认为,既然是用线程池,那还是static的比较合理。

Case II
一个跑在tomcat里的应用启动后报错,报错的信息当时没保留,大概类似如下:
This is very likely to create a memory leak.
看的完全无法理解,觉得非常诡异…

后来翻查了下tomcat自己的日志(我们的系统默认是分开了tomcat的日志以及应用的日志),发现其实是应用启动的时候失败了,相应的解决后重启一切正常。

从这点来说,tomcat的报错还是忒诡异了点,值得改进。

Case III
又碰到一个netty误用的case,还是每次创建netty客户端的连接时,NioClientSocketChannelFactory都每次new,这就导致了Netty每次都会创建Boss和Worker线程,所以好的做法都是static创建一次。

不过这个地方犯错已经不是见过一次两次了,因此我觉得Netty的API还是有必要考虑一下这点的设计。

从这些cases能看到,代码上,尤其是API的使用,要慎之又慎,否则一些小错误在大并发量的情况下会暴露的非常明显。

=============================
欢迎关注微信公众号:hellojavacases

关于此微信号:
分享Java问题排查的Case、Java业界的动态和新技术、Java的一些小知识点Test,以及和大家一起讨论一些Java问题或场景,这里只有Java细节的分享,没有大道理、大架构和大框架。

公众号上发布的消息都存放在http://hellojava.info上。