首页 » GC » 正文

【未完待续】Java后台线上服务优化小记

最近,一直负责开发公司内部的Restful服务框架,并与公司的代码审核和CI上线流程进行整合,整合的过程中需要开发线上Restful服务的启动脚本,于是,发现一些线上的服务配置没有进行过优化,因此,简单的做了下压测,尝试和对比,对线上服务进行了简单的优化,优化过程记录如下:

1. 原先GC堆的大小设置为-Xms128m -Xmx1g, 可见最小和最大设置相差太大,这会导致JDK会动态进行GC堆的扩容,影响线上性能,一般推荐将这两个参数设置为同样大小,由于我们公司规定了一个Java服务的最大内存使用是1G,因此设置为:

-Xms1g -Xmx1g

2. 原先没有设置新生代大小,-Xms128m -Xmx1g -XX:CMSInitiatingPermOccupancyFraction -XX:CMSInitiatingOccupancyFraction=70, 默认新生代和老年代比例是1:2,所以,新生代大小为42,老年代为84,那么,根据CMSInitiatingOccupancyFraction计算,84 * 0.3 = 25m< 42m, 所以,理论上是会出现分配担保失败,因此,调整为:

-Xms1g -Xmx1g -Xmn256m -XX:CMSInitiatingPermOccupancyFraction -XX:CMSInitiatingOccupancyFraction=60,

这样,每次CMS在GC堆答道60%的时候,就开始回收,保证没有分配担保失败,即使某次回收后,所有新生代的对象都进入老年代,也不会出现Stop-the-world失败。

3. 线上开启了远程调试功能,这个在线上基本不会用到,直接关闭。

4. 线上没有配置gc日志,配置了-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:logs/gc.log -verbose:gc

5. 发现有些项目使用内嵌的Tomcat服务器,Tomcat默认使用BIO,压测发现,开启日志的echo服务QPS在1200左右,非常的低,经验表明应该在2000+,所以,替换成NIO,发现QPS在2500+。

6. 服务器线程池,jetty, tomcat都使用动态可扩展的线程池,还没有查看IO线程数量以及是否有优化的余地。

7. 所有的服务使用的都是log4j,并且默认使用的是同步的Appender, 计划评估使用Disruptor异步打印日志。