转载:https://mp.weixin.qq.com/s/3IuTcDCTB3yIovp6o_vuKA

一、现象

有用户反馈访问PC首页偶尔会出现白页情况,也偶尔会收到听云的报警短信

二、监控(听云和JVMVISUAL)

刚开始去听云监控看到偶尔有几分钟报500,然后就又好了,而且没有详细的堆栈信息,但是日志显示调用的接口有熔断发生,所以初步怀疑是熔断造成,因为刚开始设置的熔断是600MS,后来调整到2s、10s,但是依然无效,依然有500的出现。换思维,通过jvisualvm进行监控,分别从cpu、内存、类、线程几个方面进行分析。经过一段时间观察得到如下结论:

1.cpu没有太大波动,看起来垃圾回收还比较合理,图形如下:

2.堆(存放类的实例、数组)看起来比较正常,也能正常回收; 非堆:(8以下,存放方法区[又叫永久区,存放类的类型信息、常量池、域信息、方法信息,大部分来源于class文件]、JVM内部处理或优化所需内存等其他meta-data);metaspace又叫元空间, 属于非堆区(java8以上,替换了之前的永久区[方法区]),图形出现了异常,呈现阶段性上升。

异常

异常

3.加载的类(共享和独有类???),发现类似异常,随时间会有阶段性增长

异常

4.线程,呈现阶段性波动,说明当时是有异常的

三、深入分析

整体的现象如上图所示,

1、首先排除线程是否存在死锁导致内存溢出。

可以借助Jconsole来查看线程是否存在死锁,或是通过jstack里查找LOCKED

通过检查以上不存在线程死锁,可以排除这种情况。

2、接着查看当时的访问量曲线,基本平稳,没有太大的流量波动(可以从听云吞吐率图形来看

3.查看内存占用最大的线程及内存增量大的线程,以及程序的问题

从图中可以看出ContainerBackgroundProccessor线程无论是从总量还是增量都是占用最高的,我们先看了我们代码中是否有内存泄漏情况,从下图可以看到程序内并没有占用很高的情况,说明程序代码并未出现内存泄漏,关键在ContainerBackgroundProccessor线程问题

于是百度,也未查到相关资料,但从名字看起来像是tomcat 容器类,于是从听云监控查找出问题的日期,发现从8月26号之后出现的,在看jeckins构建记录,在25号并未提交新功能,只是做了tomcat升级,于是对照未升级的tomcat运行状况,发现只有更新后的tomcat会出ContainerBackgroundProccessor线程一直占用较高的情况,而且所有升级的项目都有这个问题,但是由于其他项目都采用了4g内存所以不明显,但WEB又被改成2g内存了,于是猜想是由于tomcat升级后引起了内存溢出。

于是开始对比8.0.33和8.5.15.0两个版本的区别

将web项目的tomcat回退到8.0.33,经过几天的观察,运行稳定,没有出现类似问题,而且那个线程内存和cpu占用也极低,接近0。

为了稳定考虑,最终决定将所有项目先回退tomcat,但为什么新版本会出现这样的问题?于是猜想要么升级后的tomcat本身有问题,要么是配置文件,要么是JVM参数问题。如果是tomcat版本bug的话,网上肯定会有人提,本着对tomcat信任的原则,先排除另外两个。

首先,运维对JVM参数进行了调优,经过测试后再次重现,于是排除了JVM参数问题;
接着换思路,如果是配置文件的话,都有哪些不一样?于是开始对比tomcat下的几个文件context.xml和server.xml,发现了在server.xml中的  <Context path="" debug="0" crosscontext="true" reloadable="true" docBase="/data/Webapps/Web"  caseSensitive="false" /> reloadable这个参数是不一样的,于是查了下该参数:reloadable:如果这个属性设为true,  Tomcat服务器在运行状态下会监视在WEB-INF/classes和Web-INF/lib目录CLASS文件的改运.如果监视到有class文件被更新,服务器自动重新加载Web应用。虽然看起来很智能,但是一旦设置成true,ContainerBackgroundProccessor线程就会占用很高内存,将近98%,从而导致内存溢出,服务不正常等问题,理论上生产环境禁止设置成false。于是把测试环境的这个参数改了下,之前那个ContainerBackgroundProccessor线程所占内存和cpu立即降到几乎为0,回到正常。

四、结论

升级tomcat后,但tocmat配置并未按原先的配置,之前的reloadable=false设置成了reloadable=true导致了内存溢出。所以我们在生产环境对tomcat或配置的修改一定要慎重,大到容器,小到一个参数都有可能引发血案。另外就是我们要学会通过JConsole和JvmVisual来进行有效监控,便于定位和分析问题。

一个Tomcat配置参数引发的血案的更多相关文章

  1. 一次tomcat配置参数调优Jmeter压力测试记录前后对比

    使用的tomcat版本为:apache-tomcat-7.0.53 使用测试工具Jmeter版本为:apache-jmeter-2.12 1.测试前tomat的"server.xml&quo ...

  2. jenkins配置findbugs失败---不要随便忽略警告!一个因为文件所有权引发的血案

    一:背景交代 这两天组长让我这边搭一个持续集成环境.梳理了需求后,因为我们的项目都是maven项目,所以我选择了jenkins+外置maven(区别于直接从jenkins里面安装)的方案.(cento ...

  3. 一个ES设置操作引发的“血案”

    背景说明 ES版本 7.1.4 在ES生产环境中增加字段,一直提示Setting index.mapper.dynamic was removed after version 6.0.0错误.但是我只 ...

  4. springboot tomcat配置参数列表

    springboot tomcat的配置选项大全 server. Port = xxxx server. Address = server. contextPath = server. display ...

  5. 由hbase.client.scanner.caching参数引发的血案(转)

    转自:http://blog.csdn.net/rzhzhz/article/details/7536285 环境描述 Hadoop 0.20.203.0Hbase 0.90.3Hive 0.80.1 ...

  6. 一个tomcat配置多个不同端口的项目

    1.将要同时启动的项目放入不同的webapps文件夹中 2.修改tomcat安装目录下的conf-->setting.xml文件 <?xml version="1.0" ...

  7. 图文解说:Nginx+tomcat配置集群负载均衡

    图文解说:Nginx+tomcat配置集群负载均衡 博客分类: appserver nginxTomcatUbuntuLinux网络应用  作者:niumd Blog:http://ari.iteye ...

  8. Nginx+tomcat配置集群负载均衡

    开发的应用采用F5负载均衡交换机,F5将请求转发给5台hp unix服务器,每台服务器有多个webserver实例,对外提供web服务和socket等接口服务.之初,曾有个小小的疑问为何不采用开源的a ...

  9. idea 配置多个tomcat引发的血案

    javax.management.InstanceNotFoundException: Catalina:type=Server 修改tomcat端口时却仍是8080 没有使用在idea tomcat ...

随机推荐

  1. 递归遍历JSON树

    递归遍历JSON树 前几天有个人问我,json串的层级无限深,但在json串中的key是已知的,在json串中的value,有些事Object,有些是Array,如何把这些层级无限深的key所对应的v ...

  2. img加载不出来,给个默认图片。

    忽然发现,jq里也有坑,很多东西莫名其妙的被废弃了……所以,只能用原生js来做了: $('img').each(function() { if (!this.complete || typeof th ...

  3. 事务时间如何去掉wasted time

    事务时间如何去掉wasted time   事务时间 一个事务的时间是指持续时间,事务会完全记录下从事务开始到事务结束之间的时间差,那么事务的时间能真实地反映业务操作的时间吗?不能,就好像人用手按秒表 ...

  4. vue-music 关于Search(搜索页面)--上拉加载

       建立搜索框组件页面,searchBox,组件接受一个可以自定义传入的placeholder 属性.input v-model 双向绑定数据关联到query 中, 在created中监听 quer ...

  5. 洛谷P2783 有机化学之神偶尔会作弊

    题目传送门 啦啦啦,发个文纪念一下第一道在洛谷上A的黑题,一次性就过真是无比舒服-(虽然某些大佬说这题有点水……)题目其实思路不难,Tarjan缩点+LCA,不过因为是无向边,所以在Tarjan的时候 ...

  6. go chapter 2 - read file(yaml)

    func main() { data, err := ioutil.ReadFile("D:/test/widua.go") if err != nil { fmt.Println ...

  7. Grunt Gulp Browserify Webpack

    Grunt 是相比后面几个更早的项目,他依赖于各种插件的配置.这是一个很好的解决方案,但是请相信我,你不会想看到一个 300 行的 Gruntfile Gulp 提供了一个不一样的解决方案,而不是依赖 ...

  8. java.lang.NegativeArraySizeException

    两台android设备发送图片. 发送端: Socket socket = null; try { socket = new Socket(ip, 8888); byte[] bytes = Scre ...

  9. HTTP模块理解(二)

    这是我在写,用express+ajax+swig来做一个简单的应用的时候,遇到的问题.还是不太理解http模块. 后来在网上看到云栖社区的一篇<Node.js之HTTP请求与响应>,这里做 ...

  10. PHP5.3魔术方法 __invoke

    这个魔幻方法被调用的时机是: 当一个对象当做函数调用的时候, 如果对象定义了__invoke魔幻方法则这个函数会被调用, class Callme { public function __invoke ...