linux - JAVA实例疑难问题,不定期服务器负载突然断崖式下跌

查看:131
本文介绍了linux - JAVA实例疑难问题,不定期服务器负载突然断崖式下跌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

最近公司TOMCAT总是出现一些奇葩问题,如图:

这种情况大概4-5天一次吧,但是神奇的是,每一次断崖下跌后,服务是完完全全正常的!
看CDN流量:


同样的时间段,CDN这边表现的非常正常。如果服务真的宕机的话,CDN这边也会跟着断流。

刚开始我的想法是,是不是有人在爬数据或者盗链?导致日常负载流量不正常。盗链的用户那边停止服务了,我这边CPU负载就爆降。
但是经过访问请求日志分析,没有发现什么异常请求。
我分别对比了断崖暴跌前的请求数据和暴跌后的请求数据,分别统计前3小时和后3小时,基本上请求数是差不多的,而且断崖暴跌后请求还会高出不少!但是负载量前后相差3-4倍啊!
奇葩了,我整个人都是懵逼的。
请教各位对JAVA服务比较熟悉的兄弟,知道有可能是什么原因引起的吗?
再上一张详细图:


看到没有,前期CPU波动范围非常宽,忽上忽下的,但是突然断崖下跌后,就呈现一种稳定式波动,然后逐渐波动会再变得越来越大。

更新

1、GC问题考虑过,用jconsole观察,基本上是正常范围波动。毕竟当时已经优化过了,GC设定都是按照优化文档定制的。FGC频率非常低,而且最重要的是,如果是GC出问题,应用程序会没有响应的,TOMCAT会假死。
2、是所有机器都出现这种变化,所有连接都是从NGINX负载均衡分流到各个TOMCAT进群中去的,上面截图是其中一台。基本上是同一时刻,都出现这种状况。通过流量分析,也没看出什么特殊的流量,除了memcached流量比较大之外(大概1M/S),其他流量还算正常。

现在就是进了死胡同,想不到思路去判断这个问题出在哪。唯一可以利用的线索就是CPU会逐渐变得波动范围越来越大,那么也就是说峰谷和峰顶会随着时间变化而变得波动差距越来越高。有什么可能会造成这种情况呢?

解决方案

最近花了不少时间和开发配合一起DEBUG这个问题,最终问题得到解决,现在把问题的解决办法说出来给予大家参考。
断崖下跌的主要原因和memcached息息相关。首先出现这种问题的服务器,全部都是提供restfulAPI服务的。理论上来说,属于IO密集型,用不到多少计算,顶多是对数据库数据存取序列化等等。
我们首先通过perf检查JAVA线程CPU活动,发现CPU占用主要源自libzip.so。

但是我们在去除所有代码中的gzip调用后,发现该问题还是没有去除,问题依旧。
同时我们检查网络流量发现CPU断崖下跌的同时,网络流量也会出现断崖下跌,他们是完全同步的。
通过对网络流量的排查,确定所有主机在使用memcache时流量会变得越来越大,直到阿里云memcache限流的瓶颈达到,然后memcahe流量也会瞬间崩塌。
如图:

我们测试,当清理了memcache缓存后,CPU也会陡然下降,很显然问题找到了,和memcache有很大的相关性。
我们怀疑是在程序运行过程中,对memcache内数据不断的操作,当网络流量达到一定时,触发了阿里云的memcache限流,限流破坏了memcache的哈希链,导致所有缓存失效,既然缓存失效了,那么GZIP也没有压缩对象了,所以导致CPU直接断崖下跌。
我们接下来开始检查memcache的相关配置,数据在存入memcache时并没有启用gizp压缩,但是不知道为什么,一直在调用gzip。


既然配置文件没有问题,那我们决定直接修改源码,把memcache包调用GZIP的地方直接写死关闭。
但是实际上这么操作还是无法解决问题,事实上只要你的程序存在对memcache的操作,那么就会出现这个问题。
最终我们将程序中有用到memcahce的地方全部给去掉,不再使用它,问题就迎刃而解。

但是我觉得这种一刀切的方法并不太好,不过还好我们的程序数据库压力并不算大,加上服务器内存足够大,给innodb留下了足够的内存缓存,在不影响业务运营的情况下,这个问题算是暂时告一段落了。

这篇关于linux - JAVA实例疑难问题,不定期服务器负载突然断崖式下跌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆