发布或重启线上服务时抖动问题解决方案

一、问题描述

      在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后回落(图1),与此同时响应时间曲线(图2)也与load曲线一致。注:load飙高的初始时刻是应用服务端口打开,流量打入时(load具体指什么可参考http://www.cnblogs.com/amsun/p/3155246.html)。

 

图1 发布时候load飙高

 

图2 发布时候响应时间飙高

 

二、问题排查方法

     发布时对资源使用情况进行监控。

1)通过top -H -p 查找cpu使用率较高的线程,发现2129和2130这两个线程cpu使用较高。

图3 查找cpu使用率较高的线程

 

2)通过jstack打印栈信息,并将线程号2129和2130转换成16进制(printf "%x\n" 2129),分别为851和852,发现这两个线程是编译线程(表1)。此外当这两个线程cpu使用率降低后load以及响应时间也马上恢复了正常,时间点非常吻合。

 

表1 cpu使用率较高的两个线程详细信息


1

2

3

4

5

6

7

8

"C2 CompilerThread1" daemon prio=10 tid=0x00007fce48125800 nid=0x852 waiting on condition [0x0000000000000000]

java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:

- None

"C2 CompilerThread0" daemon prio=10 tid=0x00007fce48123000 nid=0x851 waiting on condition [0x0000000000000000]

java.lang.Thread.State: RUNNABLE

Locked ownable synchronizers:

- None

三、现象解释

      C2 CompilerThread线程项目启动初期cpu使用率那么高,它在干什么呢? 

      Java程序在启动的时候所有代码的执行都处于解释执行模式,只有在运行了一段时间后,根据代码方法执行的次数,或代码里循环的执行次数等达到一定的阈值才会编译成机器码,编译成机器码后执行效率会得到大幅提升,而随着执行时间进一步拉长,JVM的各种更高级的编译优化手段就会逐渐加上,例如if条件的执行状况,逃逸分析等。这里的C2 CompilerThread线程干的就是编译优化的活。

     现在貌似可以解释之前的现象了。

     在程序刚启动的时候,java还处于解释执行模式,因此服务效率很低,响应时间缓慢,处理得慢了,load自然也就高了。而当流量持续不断导入时,我们代码的很多方法执行次数不断增多,此时C2 CompilerThread线程不断收集优化信息,并且开始将一些热点代码优化编译成本地机器码,因此该线程的cpu使用率增高。而当C2 CompilerThread线程完成初始编译优化过程后,C2 CompilerThread线程的cpu使用率开始下降,与此同时优化后服务的性能大幅提升,服务响应时间也大大缩短,load也下降。

     现在的症结在于编译优化过程持续时间较长,引起抖动如何降低编译优化的持续时间呢?

四、解决思路

1)预热

      如果在服务接受线上请求之前提前完成编译优化过程,那么将能避免此种抖动情况。一般的做法是预热,有两种方法:

      a)程序主动预热:在启动完成后,程序主动的访问热点的代码,确保主要的热点代码已被编译成机器码后再放入流量,可通过-XX:+PrintCompilation来确认。

      b)复制流量预热:通过tcpcopy软件拷贝一份线上nginx的流量进行预热,完成之后再导入线上流量。

2)启动多个线程进行编译优化

     如果能加快编译优化速度,那也能降低解释执行阶段导致的抖动时间。因此可以多拿几个线程来做编译,加快达到高峰性能的速度。

     可以使用-XX:CICompilerCount参数来设置编译线程数目,这个值默认是2(之前在栈里看到有两个编译线程),我们可以加到4。

3)采用多层编译

      编译方式有三种:1)Client模式;2)Server模式;3)Tiered模式。我们服务默认是Server模式。

      Server模式是采用c2高级编译的,会比较耗时且要运行一段时间才会触发编译。 Server模式的优点是编译后程序效率较高;

      Client模式比较轻量也比较快触发(比Server模式触发快),编译优化后程序效率不如Server模式;

      Tiered模式是Client模式和Server模式的折中,一开始会启用Client模式,可以在启动后更快的让部分代码先进入编译优化阶段,之后会启动Server模式,达到程序效率最大优化的目的。

      Oracle JDK 7里的HotSpot VM已经开始有比较好的Tiered编译(tiered compilation)支持,可以设置参数-XX:+TieredCompilation来启动Tiered模式,java 8默认就是Tiered模式。

      图4是到http://www.javaworld.com/article/2078635/enterprise-middleware/jvm-performance-optimization--part-2--compilers.html截取的不同编译方式的性能比较图,横坐标是时间,纵坐标是性能。可以看出Tired模式开始阶段性能与C1相当,当到达某一时刻后性能与C2相当。

      

图4 不同编译模式的性能比较

     

五、结果分析

       简单起见采用方案2和方案3来进行优化。

       采用方案2和3之后进行了多次发布,发布时除个别机器load达到10之外,基本没有过高现象(在2~4范围内),并且短时间(2分钟)内,load都会降到较合理水平(2左右),较发布时的load来看,比优化前要好很多。

      方案2和方案3只是降低了抖动持续的时间以及抖动强度,并不能完全避免抖动。真正能避免抖动的方案应该是方案1,通过预热的方式实现平滑发布或重启。

 

 

时间: 2024-08-04 02:26:24

发布或重启线上服务时抖动问题解决方案的相关文章

线上服务 静态html CMS 发布rsync 同步

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/51279582 未经博主允许不得转载. 博主地址是:http://blog.csdn.net/freewebsys 1,静态资源 线上服务,有静态的html 比如首页,资讯页面,关于公司,加入我们,帮助页面. 都是静态的html页面.后台写了一个CMS系统,使用velocity 配置模板,然后生成html页面.在同步到线上服务器上面. 主要使用的就是 rsync 同步. 2,首先

线上服务故障处理原则

墨菲定律 任何事情都没有表面看起来那么简单 所有事情的发展都会比你预计的时间长 会出错的事情总会出错 如果担心某个事情发生,那么它更有可能发生 墨菲定律暗示我们,如果担心某种情况会发生,那么它更有可能发生,久而久之就一定会发生.这警示我们,在互联网公司,对生成环境发生的任何怪异现象和问题都不要轻视,对其背后的原因一定要调查清楚.同样,海恩法则也强调任何严重的事故背后都是很多次小问题的积累,当到一定量级后会导致质变,严重的问题就会浮出水面. 那么,我们需要对线上服务产生任何现象,哪怕是小问题,都要

索尼微软线上服务业绩喜人网络服务决定未来

索尼在GDC2011上宣布PSN(PlayStation Network)用户突破7000万,而收入则 同比增长了70%.PS3的线上虚拟世界"PlayStation Home"用户数已经达到1900万,平均游戏时间超过70分钟.目前PSN上除了948款游戏的下载服务,还有31000部电影与电视节目的下载.索尼的PSN业务高级主管Susan Panico表示:"我们的用户喜欢各种各样的娱乐方式,他们乐衷于在一个地方找到全部想要的东西." 此前,PSN一直坚持服务免费

排查Java线上服务故障的方法和实例分析

前言 作为在线系统负责人或者是一个技术专家,你可能刚刚接手一个项目就需要处理紧急故障,或者被要求帮忙处理一些紧急的故障,这个时候的情景是: (1)你可能对这个业务仅仅是听说过,而不怎么真正了解: (2)你可能没有这个故障的详细信息,比如可能仅仅是有使用方反馈服务中断了10分钟: (3)你对代码细节还没有仔细研究过. 这个时候该怎么解决问题呢?根据以前的经验,工程师们常常倾向于直接登上服务器检查代码,试图立刻修改问题.或者是把某些可能是问题的配置做修改,但并不是100%确认这就是问题的根本原因.但

solr 4 线上服务,解决慢查询导入问题。Query execution was interrupted

问题: mysql 数据库设置了慢查询断开功能,查询慢,直接把客户端杀掉. solr链接mysql 进行数据库导入.结果报错Query execution was interrupted. at org.apache.solr.handler.dataimport.DataImportHandlerException.wrapAndThrow(DataImportHandlerException.java:71) at org.apache.solr.handler.dataimport.Jdb

俏江南历经2年的O2O探索:线下服务驱动线上优化

2010年随着团购的兴起和移动互联网逐步升温,餐饮行业在互联网攻势下亦渐渐趋向网端融合.俏江南在2012年初正式决定向互联网靠拢.目前,俏江南在国内拥有74家门店,覆盖15个省份22个城市,是国内知名的高端餐饮连锁品牌.俏江南在两年的努力中都有哪些尝试? 经历: 1.团购 团购是俏江南较早迈向网端的O2O尝试.2012年3月俏江南入驻窝窝团,首次尝试网上用户向线下实体店引流.在经过一段时间尝试后,俏江南发现团购虽有引流作用,却解决不了与线下服务的冲突,比如服务能力容易与不断涌入的人流产生脱节.因

杨彪 | 一次线上游戏卡死的解决历程(文末赠书福利)

题图:StartupStock@Pixabay 编辑:冷锋 作者:杨彪 本文首发于简书云时代构架杨彪 http://www.jianshu.com/p/7885bbf153f5 事故的发生详细过程 故事是发生在几个月前的线上真实案例,我将在本文中以故事形式为大家还原这次解决游戏卡死的经历过程,其中有很多线上实战经验和技巧都值得分享借鉴的,也有作者自创的处理线上问题"四部曲"--望问闻切,还有最经典的"甩锅"秘诀. 不管白猫黑猫,能立马解决线上问题的就是好猫,线上问题

Java服务化系统线上应急和技术攻关,你必须掌握的Linux命令

上一篇文章<Java服务化系统线上应急和技术攻关,你必须拥有的那些应用层脚本和Java虚拟机命令>介绍了笔者在互联网公司里线上应急和技术攻关过程中积累的应用层脚本和Java虚拟机命令,这些脚本和命令在发现问题和定位问题的过程中起到关键作用,然而,经常会遇到一些深层次的问题,仅仅通过应用层和JVM虚拟机层的信息无法定位问题和解决问题,这时需要深入研究系统级的各种参数和信息,才能确定问题的根源原因,例如:网络超时.机器负载过高.JVM OOM.JVM和内核Bug等,这篇文章介绍那些重要的Linux

电子商务:线上与线下冲突解决之道

2010年4月22日工业和信息化部发布的数据显示,今年一季度,我国互联网网民新增2000万人,网民总数达到4.04亿人.统计显示,目前,互联网已成为人们生活.工作.学习不可或缺的工具,正对社会生活的方方面面产生深刻影响.互联网产业持续发展.据估算,1-3月份电子商务.网络广告.网络游戏.搜索引擎等市场规模同比增长均超过20%,成为互联网产业主要增长领域. 新渠道新优势:电商发展新动力 从网络用户的角度来说,随着网民规模的扩大,而且随着网民的日益成熟,网络对于网民的价值正在由 "娱乐平台"