- 如果你的项目使用了JSP作为Web页面模块,意味着TLD扫描无法避免,但是我们可以通过配置来告诉Tomcat,只扫描那些包含TLD文件的JAR包。方法是,找到Tomcat的`conf/`目录下的`catalina.properties`文件,在这个文件里的jarsToSkip配置项中,加上你的JAR包。
```
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=xxx.jar
```
## 关闭WebSocket支持
Tomcat会扫描WebSocket注解的API实现,比如`@ServerEndpoint`注解的类。我们知道,注解扫描一般是比较慢的,如果不需要使用WebSocket就可以关闭它。具体方法是,找到Tomcat的`conf/`目录下的`context.xml`文件,给Context标签加一个**containerSciFilter**的属性,像下面这样。
更进一步,如果你不需要WebSocket这个功能,你可以把Tomcat lib目录下的`websocket-api.jar`和`tomcat-websocket.jar`这两个JAR文件删除掉,进一步提高性能。
## 关闭JSP支持
跟关闭WebSocket一样,如果你不需要使用JSP,可以通过类似方法关闭JSP功能,像下面这样。
我们发现关闭JSP用的也是**containerSciFilter**属性,如果你想把WebSocket和JSP都关闭,那就这样配置:
## 禁止Servlet注解扫描
Servlet 3.0引入了注解Servlet,Tomcat为了支持这个特性,会在Web应用启动时扫描你的类文件,因此如果你没有使用Servlet注解这个功能,可以告诉Tomcat不要去扫描Servlet注解。具体配置方法是,在你的Web应用的`web.xml`文件中,设置`<web-app>`元素的属性`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`里面的`<absolute-ordering>`元素直接指定了哪些JAR包需要扫描`web fragment`,如果`<absolute-ordering/>`元素是空的, 则表示不需要扫描,像下面这样。
## 随机数熵源优化
这是一个比较有名的问题。Tomcat 7以上的版本依赖Java的SecureRandom类来生成随机数,比如Session ID。而JVM 默认使用阻塞式熵源(`/dev/random`), 在某些情况下就会导致Tomcat启动变慢。当阻塞时间较长时, 你会看到这样一条警告日志:
>
`<DATE>` org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [8152] milliseconds.
这里需要注意的是,Engine元素里也配置了这个参数,这意味着如果你的Tomcat配置了多个Host(虚拟主机),Tomcat会以并行的方式启动多个Host。
## 本期精华
今天我讲了不少提高优化Tomcat启动速度的小贴士,现在你就可以把它们用在项目中了。不管是在开发环境还是生产环境,你都可以打开Tomcat的启动日志,看看目前你们的应用启动需要多长时间,然后尝试去调优,再看看Tomcat的启动速度快了多少。
如果你是用嵌入式的方式运行Tomcat,比如Spring Boot,你也可以通过Spring Boot的方式去修改Tomcat的参数,调优的原理都是一样的。
## 课后思考
在Tomcat启动速度优化上,你都遇到了哪些问题,或者你还有自己的“独门秘籍”,欢迎把它们分享给我和其他同学。
不知道今天的内容你消化得如何?如果还有疑问,请大胆的在留言区提问,也欢迎你把你的课后思考和心得记录下来,与我和其他同学一起讨论。如果你觉得今天有所收获,欢迎你把它分享给你的朋友。