抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Tomcat性能优化

嵌入式Tomcat

为什么要嵌入式

​ 为什么需要嵌入式启动,我们由之前一般的Tomcat启动可知,Tomcat组件非常多,启动流程步骤比较多,但是往往我们一般就只需要简单快速的部署一个Web项目,所以简单实用的嵌入式Tomcat就诞生而来。

部署复杂度

​ 如果按照传统部署,我们需要下载Tomcat,同时需要配置服务器,同时还需要修改端口,同时也要避免应用系统的jar包与服务器中存在的lib包的冲突,所有的这些都会增加部署的复杂度,并且这种配置大部分还是一次性的,不可重用。如果你遇到大规模的服务器集群环境(部署N多个应用)时,会增加我们的运维成本,如果按照嵌入式启动,这种方式几乎是一键式的,可以把以上问题轻松的解决。

架构约束

​ Tomcat启动的时候默认不单单只启动了HTTP协议,还有AJP协议等等,如果我们就只想简简单单的启动一个HTTP服务,同时不想启动那些多组件,可以使用嵌入式Tomcat,避免在部署启动时的架构约束。

微服务架构

​ 现在微服务已经是主流的架构,其中微服务中每项服务都拥有自己的进程并利用轻量化机制实现通讯。这些服务都是围绕业务功能建立,可以自动化部署或独立部署。将微服务架构与Tomcat技术相结合,可以轻松将系统部署到云服务器上。当前SpringBoot支持的嵌入式服务器组件就是Tomcat.

嵌入式启动实战

启动Servlet
导入POM
1
2
3
4
5
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.53</version>
</dependency>
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TomcatTest {

public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
HttpServlet servlet = new HttpServlet() {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello word");
}
};
Context context = tomcat.addContext("/demo", null);
tomcat.addServlet(context, "servlet", servlet);
context.addServletMapping("/test", "servlet");

tomcat.init();
tomcat.start();
tomcat.getServer().await();
}
}

​ 通过实战可知,我们添加了一个HttpServlet提供对外服务,这样我们的Tomcat就可以简单的提供一个Servlet服务,而不提供页面访问(JSP、HTML等),可以非常灵活的控制Servlet的加载以及请求链接的分配,而不受限制于Context与应用的一一对应关系。

嵌入式启动应用
导入POM
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 嵌入式Tomcat -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.53</version>
</dependency>
<!-- 嵌入式Tomcat的JSP支持 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.53</version>
</dependency>
代码
1
2
3
4
5
6
7
8
9
10
public class TomcatTest {

public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
tomcat.addWebapp("/test","D:\\workspace\\OpenSource\\webapps\\manager");
tomcat.init();
tomcat.start();
tomcat.getServer().await();
}
}

嵌入式常用的配置

  • setConnector: 用于设置链接器,包括协议、I/0、端口、压缩、加密等等。

  • setHost: 用于设置Host

  • setBaseDir: 用于设置临时文件的目录,这些目录用于存放JSP生成的源代码及Class文件

Tomcat性能优化

server.xml优化

​ 其实网络的Tomcat配置信息的文章很多,五花八门,一般推荐使用Tomcat自身提供的配置帮助文档,因为你只要下载了Tomcat,并且启动了它,那么Tomcat就会提供最官方,最准确的官方参数说明文档。

​ 下载Tomcat后不要删掉默认的程序包.

一般Tomcat启动后,不改动端口的话,默认是8080,我们输入localhost:8080 访问下。

​ 这个会出现一个英文的Tomcat环境界面,包括各种文档说明信息都在此,我推荐使用谷歌浏览器,因为这个浏览器自带翻译功能。

Connector连接器

IO模型优化策略

连接器模式改为NIO模式,NIO模式最大化压榨了CPU,把时间片更好利用起来,NIO适合大量长连接。

最大线程优化策略

​ maxThreads属性设置为简单200.这对于单个核心计算机来说很好,但是可以根据生产计算机上的处理器数量线性增加。在具有四个处理器的计算机上,将此值设置为800到1000之间的任何值都不会导致问题。如果配置的数量最终远远超过所需的线程数,则当服务器负载较低时,线程池将自然缩减此数字。

压缩gzip连接器传输

客户端和服务器之间的任何主要是文本的通信,无论是HTML,XML还是简单的Unicode,都可以使用简单的标准GZIP算法定期压缩高达90%。这可以对减少网络流量产生巨大影响,允许响应更快地发送回客户端,同时允许更多网络带宽可用于其他网络繁重的应用程序。

1
2
3
4
5
6
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" executor="tomcatThreadPool" URIEncoding="utf-8"
compression="on"
compressionMinSize="50" noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" />
配置线程池 Executor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Executor 
name="tomcatThreadPool"<!--线程名称-->
namePrefix="catalina-exec-"
maxThreads="150"<!--最大处理连接数线程-->
minSpareThreads="4" /><!--保留最少线程数-->
<!-- 将原有的Connector 替换为带有线程池的Connector如下,其实servlet.xml已经有了,只要打开就可以了,将原来的去掉 -->
<Connector
executor="tomcatThreadPool"
port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
minProcessors="5"<!-- 同时处理请求的最小数 -->
maxProcessors="75"<!-- 同时处理请求的最大数 -->
acceptCount="1000" /><!-- 接受最大并发数量 ,超过这个数量就会返回连接被拒绝 -->
Executor的属性

去除valve访问tomcat记录
1
2
3
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
关闭自动重载,热部署方式

关闭自动重载,默认是true(不同版本中有差异),自动加载增加运行开销并且很容易内存溢出

web.xml优化

去掉不必要的servlet

如当前应用是REST应用(微服务):

  • 去掉不必要的资源:JspServlet

  • seesion也可以移除

JspServlet优化
  • checkInterval - 如果“development”属性为false且“checkInterval”大于0,则使用后台编译。“checkInterval”是查看JSP页面(包括其附属文件)是否需要重新编译的两次检查时间间隔(单位:秒)。缺省值为0秒。

  • classdebuginfo - 类文件在编译时是否显示调试(debugging)信息? true 或false,缺省为true。

  • classpath - 编译servlet时要使用的类路径,当ServletContext 属性org.apache.jasper.Constants.SERVLET_CLASSPATH未设置的情况下,该参数才有效。在Tomcat中使用到Jasper时,该属性总被设置。缺省情况下,该路径基于你当前的web应用动态生成。

  • compiler – Ant将要使用的JSP页面编译器,请查阅Ant文档获取更多信息。如果该参数未设置,那么默认的Eclipse JDT Java编译器将被用来代替Ant。没有缺省值。

  • compilerSourceVM - 编译源文件时采用哪一个JDK版本?(缺省为 JDK 1.4)

  • compilerTargetVM - 运行类文件时采用哪一个JDK版本?(缺省为 JDK 1.4)

  • development - 是否让Jasper用于开发模式?如果是,检查JSPs修改的频率,将通过设置modificationTestInterval 参数来完成。true 或false,缺省为true。

  • displaySourceFragment - 异常信息中是否包含出错的源代码片段?true 或false,缺省为true。

  • dumpSmap - JSR45调试的SMAP信息是否转存到文件?true 或false,缺省为false。当suppressSmap 为true时,该参数为false。

  • enablePooling - 确定是否共享标签处理器,true或false,缺省为true。

  • engineOptionsClass - 允许指定的类来配置Jasper。如果没有指定,则使用默认的Servlet内置参数(EmbeddedServletOptions)。

  • errorOnUseBeanInvalidClassAttribute - 在一个useBean action中,当类属性的值不是一个合法的bean class时,Jasper是否抛出异常?true或false,缺省为true。

  • fork - 是否让Ant派生出JSP页面多个编译,它们将运行在一个独立于Tomcat的JVM上。true 或者false, 缺省为true.

  • enStringAsCharArray - 是否把字符串转换为字符数组?在某些情况下会改善性能。缺省为false.

  • eClassId - 当使用标签时,发送给Internet Explorer的class-id的值。缺省为:8AD9C840-044E-11D1-B3E9-00805F499D93。

  • javaEncoding - 生成java源文件时采用的Java文件编码。缺省为UTF-8。

  • keepgenerated - 是否保存每个页面生成的java源代码,而不删除。true 或 false,缺省为true。

  • mappedfile - 是否对每个输入行都用一条print语句来生成静态内容,以方便调试。true 或 false,缺省为true。

  • modificationTestInterval - 检查JSP页面修改的间隔时间(单位:秒),在间隔时间内,JSP及其包含的页面将不会检查。当间隔时间为0时,JSP每一次访问都会被检查。仅仅适用于开发模式(参数development为true)。缺省为4秒。从JSP每次开始访问开始计时,N秒以后检查,变化就编译,每次访问都刷新开始时间,默认4秒

  • scratchdir - 当编译JSP页面时使用的scratch 目录。缺省为当前WEB应用的工作目录。

  • suppressSmap - 是否禁止JSR45调试时生成SMAP信息?true 或 false,缺省为false。

  • trimSpaces - 是否去掉模板文本中行为和指令之间的空格。缺省为false。
    xpoweredBy - 确定生成的Servlet是否加上X-Powered-By 响应头?true 或 false,缺省为false。

Tomcat版本升级

评论