维护公司的一个项目, 运行在jvm 上的scala 语言编写; Akka Actor System 实现的一个web 系统。

问题: 项目启动后就能占用50% cpu 资源, 8核cpu的情况下, 由于刚启动没有任何负载,  占用cpu明显过多。

cpu 占用过多可能的几种情况:

  1. 一直在GC , gc overhead exceed limit
  2. 死循环,占用线程不释放
  3. 线程过多, 线程切换上下文开销大

由于项目刚启动就占用大cpu ,怀疑是项目中的定时任务初始化不当,将定时任务代码注销,  启动后cpu 占用没变,排除定时任务问题

通过jdk自带的分析工具,进行分析, 一般情况下我们都设置了环境变量,可以在命令行下直接使用, jdk自带了很多分析工具,在对应安装目录的bin路径下,可以自行搜索其用法。又由于该项目运行在jvm上,jvm具有跨平台的熟悉,所以直接在window下进行分析。Linux 下没有图形化界面,需要些额外设置。

打开cmd,  输入:jvisualvm

如图所示:左上角有可以分析的运行在jvm上的进程。可以看到也可以远程分析,需要额外的设置,对于我们这个问题,可以本地分析。

kafka占用cpu kafka cpu占用率很高_定时任务

启动程序,重新开一个cmd, 我本地项目通过 java -jar xxx.war 启动,然后就可以在分析界面看到对应的xxx.war进程。如图所示

kafka占用cpu kafka cpu占用率很高_kafka占用cpu_02

双击打开,可以看到,好多分析项, 有gc情况,cpu情况,线程数情况。

 

kafka占用cpu kafka cpu占用率很高_定时任务_03

线程数接近500, 刚启动线程数接近500,线程数过高,可以向下翻动,发现很多线程都是在休眠状态,并没有得到执行。 同时可以检测没有死锁发生,不会线程占用cpu不释放。在到gc 面板看下gc频率。

kafka占用cpu kafka cpu占用率很高_scala_04

 通过上图分析,gc 频率正常。

综上,怀疑是项目初始化不当,导致线程数过多, 检查代码,发现项目初始化时,容器初始化过多, 一个容器初始化会有很多的守护线程,导致线程数过多,cpu占用过多。

ActorSystem多次, 查阅资料,发现akka官网有对actorsystem 的说明:

kafka占用cpu kafka cpu占用率很高_kafka占用cpu_05

多实例化的ActorSystem 也只实例化一次,重新编译,运行,发现线程数降下来了,cpu也降下来了。