优化并提高Tomcat启动速度

清理你的Tomcat

1. 清理不必要的Web应用

删除掉webapps文件夹下不需要的工程,比如host-manager、example、doc等这些默认的工程,还有以前添加的但是现在用不着的工程。每次启动Tomcat,都会重新部署这些工程。

2. 清理XML配置文件

Tomcat在启动的时候会解析所有的XML配置文件,但是XML文件的解析需要不小的代价,因此我们需要尽量保持配置文件的简洁。

3. 清理JAR文件

还可以删除不需要的JAR文件。JVM的类加载器在加载类时,需要查找每一个JAR文件,去找到所需要的类。如果删除了不需要的JAP文件,查找的速度就会快一点。例如:WEB应用的lib目录下不应该出现Servlet API 或者 Tomcat自身的JAR,这些JAR有Tomcat负责提供。所以你的项目中对Servlet API的依赖应该指定为<scope>provided</scope>

4. 清理其他文件

及时清理日志,删除logs文件夹下不需要的日志文件。同样还有work文件夹下的catalina文件夹,它其实是Tomcat把JSP转换为Class文件的工作目录。

禁止Tomcat TLD扫描

Tomcat为了支持JSP,在应用启动的时候会扫描JAR报里的TLD文件,加载里面定义的标签库,所以在Tomcat的启动日志里,你可能会碰到这个提示:

07-Jun-2019 11:09:51.577 信息 [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.

Tomcat的意思是,我扫描了你的Web应用下的JAR包,发现JAR包里没有TLD文件。建议你配置一下Tomcat不要去扫描这些JAR包,这样可以提高Tomcat的启动速度,并节省JSP编译时间。

怎么配置不去扫描这些JAR包呢,这里分两种情况:

  • 如果你的项目没有使用JSP作为Web页面模板,而是使用了别的模板引擎,你完全可以把TLD禁止掉。方法是,找到Tomcat的conf/目录下的context.xml文件,在这个文件里Context标签下,加上JarScanner和JarScanFilter标签:
<Context>
    <JarScanner>
        <JarScanFilter defaultTldScan="false" />
    </JarScanner>
</Context>

springboot配置:

@Bean
public TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
            }
        };
}
或者配置文件配置:
server.tomcat.additional-tld-skip-patterns=123.jar

  • 如果你的项目使用了JSP作为Web页面模块,那么意味着TLD扫描无法避免,但是我们可以通过配置来告诉Tomcat,只扫描那些包含TLD文件的JAR包。方法:找到Tomcat的conf/目录下的catalina.properties文件,在这个文件里的jarsToSkip配置项中,加上你的Jar包。
tomcat.util.scan.StandardJarScanFilter.jarsToScan=123.jar

关闭WebSocket支持

Tomcat会扫描WebSocket注解的API实现,比如@ServerEndPoint注解的类。我们知道,注解扫描一般是比较慢的,如果不需要使用WebSockets就可以关闭它。具体的方法是,找到Tomcat的conf/目录下的context.xml文件,给Context标签加一个containerSciFilter的属性,如下所示:

<!--关闭WebSocket支持-->
<Context containerSciFilter="org.apache.tomcat.websocket.server.WsSci">
  ...
</Context>

更进一步,如果你不需要WebSocket这个功能,你可以把Tomcat lib目录下的websocket-api.jar和tomcat-websocket.jar这两个JAR文件删除掉,进一步提高性能。

关闭JSP支持

和关闭WebSocket一样,如果你不需要使用JSP,可以通过类似方法关闭JSP功能,如下:

<!--关闭JSP功能-->
<Context containerSciFilter="org.apache.jasper.servlet.JasperInitializer">
  ...
</Context>

也可以配置同时关闭WebSocket和JSP功能:

<!--关闭WebSocket支持-org.apache.tomcat.websocket.server.WsSci-->
<!--关闭JSP功能-org.apache.jasper.servlet.JasperInitializer-->
<Context containerSciFilter="org.apache.jasper.servlet.JasperInitializer|org.apache.tomcat.websocket.server.WsSci">
  ...
</Context>

禁止Servlet注解扫描

servlet3.0引入了注解Servlet,Tomcat为了支持这个特性,会在Web应用启动时扫描你的类文件,因此如果没有使用Servlet主借这个功能,可以告诉Tomcat不要去扫描Servlet注解。具体配置方法是在你的Web应用的web.xml文件中,设置<web-app>元素的属性metadata-complete=”true“>,如下面所示:

<web-app metadata-complete="true">
  ...
</webapp>

metadata-complete的意思是,web.xml里配置的Servlet是完整的,不需要再去类库中找Servlet的定义。

配置Web-Fragment扫描

Servlet3.0还引入了”Web模块部署描述符片段“的web-frafment.xml,这是一个部署描述文件,可以完成web.xml的配置功能。而这个web-fragment.xml文件必须存放在JAP文件的META-INF目录下,而JAR包通常放在WEB-INF/lib目录下,因此Tomcat需要对JAR文件进行扫描才能支持这个功能。

你可以通过配置web.xml里面的<absolute-ordering>元素直接指定那些JAR包需要扫描web fragment,如果<absolute-ordering/>元素是空的,则表示不需要扫描,如下所示:

<web-app>
    ...
    <absolute-ordering />
    ...
</web-app>

随机数熵源优化

Tomcat7以上的版本依赖Java的SecureRandom类来生成随机数,比如Session ID。而JVM默认使用阻塞式熵源(/dev/random),在某些情况下就会导致Tomcat启动变慢。解决方案是通过设置,让JVM使用非阻塞式的熵源。
我们可以设置JVM参数:

-Djava.security.egd=file:/dev/./urandom

或者是设置java.security文件,位于$JAVA_HOME/jre/lib/security目录之下: securerandom.source=file:/dev/./urandom

这里需要注意, /dev/./urandom中间有个./的原因是Oracle JRE中的BUG,Java8里面的SecureRandom类已经修正了这个bug。阻塞式的熵源(/dev/random)安全性较高,非阻塞式的熵源(/dev/urandom)安全性会低一些。因此如果你对随机数的要求比较高,可以考虑使用硬件方式生成熵源。

并行启动多个Web应用

Tomcat启动的时候,默认情况下Web应用都是一个一个启动的,等所有Web应用全部启动完成,Tomcat才算启动完毕。如果在一个Tomcat下有多个Web应用为了优化启动速度,可以配置多个应用程序并行启动,可以通过修改server.xml中Host元素的startStopThreads属性来完成。
startStopThreads的值表示你想用多少线程来启动你的Web应用,如果设成0表示你要并行启动Web应用,如下所示:

    <Engine name="Catalina" defaultHost="localhost" startStopThreads="0">
    <!--startStopThreads:Engine 在启动 Host 子元素时将会并发使用的线程数目。如果设置为0,将会使用 Runtime.getRuntime().availableProcessors() 的值。设置为负数,将会使用Runtime.getRuntime().availableProcessors() + value 的值,如果结果小于1,将会使用1个线程。如果没有指定,默认值为 1 -->
        <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true" startStopThreads="0">
            <!--startStopThreads:Host 在启动子 Context 元素时会并发使用的线程数。如果自动部署被使用的话将会使用该线程池部署新的 Context-->
            ...
        </Host>
    </Engine>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容