记一次单个服务将cpu占满的问题排查

1、发生故障

今天发现服务查询一直卡住,就看了一下服务器:java

图片描述

当时就愣住了就这一个服务就把CPU占满了,再看了下端口号:nginx

图片描述

出现了大量的CLOSE_WAIT。看到这里我就只有一个想法:程序代码有问题或者是配置的问题数据库

2、排查

为此我先重启了服务并加上参数用jconsole查看服务情况:
-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=10000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=falsevim

再打印GC日志:
-verbose:gc
-Xloggc:/usr/app/ydjAgent/gc_log
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps 数组

启动参数太长了我又把它添加到环境变量里:
vim /etc/profile服务器

export JAVA_OPTS='-Xms1024m -Xmx4096m -Djava.rmi.server.hostname=120.0.0.1 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -verbose:gc -Xloggc:/usr/app/ydjAgent/gc_log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps'架构

根据jconsole概览和GC日志能够看的出,是由于系统频繁进行GC致使的:app

图片描述

图片描述

通常状况下,young gc频繁是正常的,full gc若是很是频繁,通常状况下有问题的就是接口查询中的集合的数据,存起来了,一直没删除,致使gc没有及时回收。spa

而后将堆信息dump下来后用Eclipse memory analyze分析了一下,发现char[]数组和byte[]数组占了大部份内存。设计

综上分析后查明,由于业务须要统计一个月内的全部订单中的商品以及品牌排行,由于原有表的设计的主键id是UUID,服务在启动的时候只给了最大4G内存,即便是只查询订单id,都占了很大一部分空间,更别说后面查询出来的订单信息会占用更大的内存空间,而由于这样,数据库的压力和应用的压力也会很大,应用一直处于FULL GC状态,把cpu占满。

3、解决办法

由于该应用和数据库是在同一个服务器上,因此就先把应用部署到另外一个服务器上而后用nginx经过内网将请求转发,把内存设置8G,缓解原来服务器的CPU压力,即使如此,在数据访问的时候仍是对数据库形成了很大的压力。由于我代码写的太烂了哈哈。。事发以后先向老板作了汇报,老板表示理解。。给我时间去从新设计原有的架构。。。不说了写代码去。。。

相关文章
相关标签/搜索