记一次mongodb的生产事故—项目线程数飙升

1. 问题起因

某个项目上线了几天后,突然项目的线程数彪升。触发了报警。

查看Falcon平台,发现在9:40的时候,项目的线程数突然彪升。

image.png

2. 排查流程

登录对应服务器:

  1. 使用top命令查询PID(57021),且发现CPU使用率并没有上升;
  2. 使用jstat -gcutil 57021 250 100打印GC情况发现GC情况也比较正常,不是GC线程的问题。
  3. 使用jstack 57021 >test.log将项目的线程堆栈信息打印到文件中。

发现test.log文件存在很多下图所示的线程信息:

image.png

  1. 使用jstack -l 57021 | grep cluster | wc -l命令进行统计,发现项目中cluster线程数800多个。

由此推测,应该是com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.waitForSignalOrTimeout(DefaultServerMonitor.java:226)位置的代码原因。

3. 查询源码

DefaultServerMonitor推测,可能是一个Mongo监控检查的功能。

image.png

而此线程启动是创建DefaultServer时。

image.png

创建MongoClient对象时会创建DefaultServer。

在网上百度了下,没有人反应mongodb项目运行一段时间后monitorThread线程数飙升。而根据源码发现,每一次去创建MongoClient对象时,都会去开启monitorThread线程。所以推测:项目在启动后,有动态创建MongoClient对象的动作。

4. 问题定位

因为我们有一个接口,需要根据用户上送的参数去动态的切换mongo库。而切换库时,每次都是创建MongoClient对象(不是从缓存中获取)。且创建MongoClient对象都会启动monitorThread线程(且不会被回收)。所以当大量访问某个接口时,会使得项目的线程数彪升。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容