如何优化并提供 Tomcat的启动速度

如果大家觉得文章有错误内容,欢迎留言或者私信讨论~

  有时候我们可能会遇到 Tomcat 启动特别慢的情况,特别是遇到新项目上线的情况下可能需要重启服务,这时候我们希望 Tomcat 能够快速启动提供服务。

  实际上,这个话题官网有提及过,下面针对 Tomcat 8.5 和 9.0 的版本,给出几条明确的建议,可以现学现用。

清理你的 Tomcat

1. 清理不必要的 Web 项目

  首先我们要删除 webapps 文件夹下的不需要的工厂,一般是 host-manager、example、doc 等这些默认的工程,可能还有之前添加的但是现在用不到的项目,这些最好全部删掉。如果你观察日志会发现每次 Tomcat 启动的时候都会重新部署这些工程。

2. 清理 XML 配置文件

  Tomcat 在启动时会解析配置文件创建初始化启动对应组件,而 XMl 文件解析的代价可不小,因此我们要尽量保证配置文件的简介,需要解析的东西越少,速度自然就会快。

3. 清理 JAR 文件

  我们还可以清理不需要的 JAR 文件。JVM 的类加载器在加载类时,需要查找每个 JAr 文件,去找到所需要的类。
  这里需要注意的是:Web 应用中的 lib 目录下不应该出现 Servlet API 或者 Tomcat 自身的 JAR, 这些 JAR 由 Tomcat 负责提供。如果你试用 Maven 来构建你的应用,对 Servlet API 的依赖应该指定为 <scpoe>provided</scope>

4. 清理其他文件

  剩下的你还可以清理日志文件,删除 logs 文件夹下不需要的日志文件。同样还有 work 文件夹下的 catalina 文件夹,它其实是 Tomcat 把 JSP 转换为 Class 文件的工作目录。有时候我们也许会遇到修改了代码,重启了 Tomcat,但是仍没效果,这时候便可以删除掉这个文件夹,Tomcat 下次启动的时候会重新生成。

禁止 Tomcat TLD 扫描

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

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 包,没有发现 TLD 文件。

  最好去配置一下 Tomcat 不要去扫描这些 JAR 包,这样可以提高 Tomcat 的启动时间,并节省 JSP 的编译时间。那么如何配置不去扫描这些 JSP 包呢?这里分为两种情况:

  • 第一种是项目没有 JSP 作为 Web 页面模板,是应用 Velocity、或者前后端分类的模式,你就可以把 TLD 扫描禁止掉。方法是,找到 Tomcat 的 conf/ 目录下的 content.xml 文件,加上 JarScanner 和 JarScanFilter 子标签,像下面这样:

在这里插入图片描述

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

关闭 WebSocket 支持

  Tomcat 会扫描 WebSocket 注解的 API 实现,比如@ServerEndpoint注解的类。注解扫描一般是比较慢的,如果不需要就可以关闭它。具体方法是,找到 Tomcat 的 conf/ 目录下的 content.xml 文件,给 Context 标签加一个 containerSciFilter 的属性,像下面这样:
在这里插入图片描述

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

关闭 JSP 功能支持

  如果你不需要 JSP 功能,可以像下面这样(就跟关闭 WebSocket 一样):
在这里插入图片描述

禁止 Servlet 注解扫描

  如果你也不需要 Servlet 注解这个功能,可以告诉 Tomcat 不去扫描。具体的实现方式是去 Web 应用的 web.xml 文件中,设置元素的属性metadata-complete=“true”,像下面这样:
在这里插入图片描述
  metadata-complete的意思是,web.xml里配置的 Servlet 是完整的,不需要再去库类中找 Servlet 的定义。

配置Web-Fragment 扫描

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

  你可以通过配置web.xml里面的元素直接指定了哪些 JAR 包需要扫描web fragment,如果元素是空的, 则表示不需要扫描,像下面这样:

在这里插入图片描述

随机数熵源优化

  是比较一个出名的问题,Tomcat 7 以上的版本依赖 Java 的SecureRandom 类来生成随机数,比如 Session ID。而 JVM 默认使用阻塞式熵源(/dev/random), 在某些情况下就会导致 Tomcat 启动变慢。当阻塞时间较长时, 你会看到这样一条警告日志:

org.apache.catalina.util.SessionIdGenerator createSecureRandomINFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [8152] milliseconds.

  具体的原理在这里。这里我们谈论的是解决方案:通过设置,让 JVM 使用非阻塞式的熵源。

  设置 JVM 参数

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

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

网友总结

  一般来说,以上的方案部分是很少用到的。顺便再让我们来看看网友们的几种解决方案:

  1. 调大vm xms xmx避免反复扩容堆内存
  2. 换上固态硬盘可以提速xml文件读取
  3. server.xml去掉监听
  4. 去掉不要的ajp
  5. 去掉多余的连接器
  6. 线程池的核心线程设置延迟初始化
  7. 去掉access log,因为nginx里已有access log
  8. 减少项目里多余的jar
  9. 精确设置mvc注解的包扫描范围
  10. xml spring bean设置延迟初始化
  11. 数据库连接池初始化数量减少
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值