个人博客原文:http://www.relaxheart.cn/to/master/blog?uuid=68
Tomcat服务器是一个免费的开源的Web应用服务器。Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,有Apache、Sun和其他一些公司及个人共同开发完成的。它完全基于Java平台,也是目前使用最广泛的Servlet容器之一。Tomcat安装完成后,目录结构如下图:
bin目录下存放的是Tomcat的启动、关闭程序;
conf目录下是Tomcat服务器的配置文件,包括Tomcat的权限管理、线程池、端口号等配置信息;
webapps下存放部署在Tomcat下的Web应用,每个应用对应一个文件夹或者一个war包。
启动Tomcat时,只要运行bin目录下的startup.sh(linux下, windows下是startup.bat)文件即可。下面是我的机器tomcat启动后的显示信息,控制台最后几行输出:
26-Mar-2019 22:17:08.238 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-80"]
26-Mar-2019 22:17:08.310 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-jsse-nio-443"]
26-Mar-2019 22:17:08.312 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
26-Mar-2019 22:17:08.314 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 146478 ms
日志里面第一行结尾“http-nio-80” 说明我是使用80端口启动的,最后一行“startup in 146478ms”说明本次启动耗时146478毫秒(时间是有点久啊,这个可能是和我的应用复杂度有关,当然另外一个原因也就是今天记录的重点,Jvm调优 - Tomcat启动加速)。
下面将开始学习如何通过配置合理的JVM参数,来加快Tomcat的启动速度。
我们在使用startup.sh脚本启动Tomcat时,startup.sh调用了bin目录下的catalina.sh(linux下, windows下是catalina.bat)脚本。如果需要配置Tomcat的JVM参数,可以僵蚕数据写入catalina.sh中。打开catalina.sh可以看到,在文件中有类似如下一段说明:
# CATALINA_OPTS (Optional) Java runtime options used when the "start",
# "run" or "debug" command is executed.
# Include here and not in JAVA_OPTS all options, that should
# only be used by Tomcat itself, not by the stop process,
# the version command etc.
# Examples are heap size, GC logging, JMX ports etc.
#
# // 省略一部分
#
# JAVA_OPTS (Optional) Java runtime options used when any command
# is executed.
# Include here and not in CATALINA_OPTS all options, that
# should be used by Tomcat and also by the stop process,
# the version command etc.
# Most options should go into CATALINA_OPTS.
这段说明显示,配置环境变量CATALINA_OPTS或者JAVA_OPTS都可以设置Tomcat的JVM优化参数。就startup.sh而言,将参数配置在任何一个环境变量中都可以生效的。根据说明的建议,类似于堆大小、GC日志和JMX端口等推荐配置在CATALINA_OPTS中。为了获取Tomcat启动是的GC信息,可以在catalina.sh中加入:
set CATALINA_OPTS=-Xloggc:gc.log -XX:+PrintGCDetails
再次启动Tomcat,发现在bin目录下生成文件gc.log,记录着启动时的GC信息。在我的启动过程中一共记录32次GC,其中Full GC两次。如果可以去掉这些GC过程,那么启动速度无意会变快。注意这两段Full GC的日志:
[Full GC (Ergonomics) [PSYoungGen: 1537K->1674K(4096K)] [ParOldGen: 7129K->7129K(7168K)] 8074K->8019K(9216K), [Metaspace: 3357K->3357K(1056768K)], 0.1213761 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
[Full GC (Ergonomics) [PSYoungGen: 944K->890K(2048K)] [ParOldGen: 7129K->7129K(7168K)] 8074K->8019K(9216K), [Metaspace: 3357K->3357K(1056768K)], 0.1213761 secs] [Times: user=0.06 sys=0.00, real=0.06 secs]
在发生Full GC时,永久去回收了部分数据,如果拥有一个较大的永久去,则可以避免发生Full GC。同时,为了减少Minor GC的次数,也需要增大新生代。为此尝试使用一下参数启动Tomcat:
set CATALINA_OPTS=%CATALINA_OPTS% -Xmx32M -Xms32M
在运行Tomcat,启动完成后查看日志。发现还有一次Full GC。这次Full GC是因为代码中显示使用了System.gc()导致的。因此,可以使用一下参数,禁用显示GC:
set CATALINA_OPTS=%CATALINA_OPTS% -XX:+DisableExplicitGC
至此,在Tomcat的启动过程中,已经找不到了Full GC的踪迹,同时Minor GC也较少到了14次。
在堆内存32MB不变的前提下,为了能进一步减少Minor GC的次数,可以扩大新生代的大小:
set CATALINA_OPTS=%CATALINA_OPTS% -XX:NewRatio=2
在这个较大的新生代下,Minor GC的刺手较少到了2次,并且没有Full GC发生,为了加快Minor GC的速度,在多核计算机上可以考虑使用新生代并行回收收集器,加快仅有的2次Minor GC的速度:
set CATALINA_OPTS=%CATALINA_OPTS% -XX:+UserParallelGC
由于JVM在加载类时,处于安全考虑,会对class进行校验和认证,如果类文件是可信的,为了加快程序的运行速度,也可以考虑禁用这些校验:
set CATALINA_OPTS=%CATALINA_OPTS% -Xverify:none
至此,完成了一个简单的加快Tomcat启动过程的实验。再次启动Tomcat服务器,在站长的计算机(腾讯云主机)上最后机上的输出如下:
26-Mar-2019 23:26:04.282 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-80"]
26-Mar-2019 23:26:04.312 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-jsse-nio-443"]
26-Mar-2019 23:26:04.323 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
26-Mar-2019 23:26:04.342 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 21994 ms
到这里就结束了,但是这篇文件中对于Tomcat启动加速,JVM调优只用到了一小部分优化配置方法,还有很多的优化配置,关于CATALINA_OPTS 与 JAVA_OPTS的,感兴趣的朋友去多多试一试。