6

如何对Tomcat进行性能优化?

 1 year ago
source link: https://server.51cto.com/article/745251.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

如何对Tomcat进行性能优化?

作者:JAVA旭阳 2023-01-30 08:30:09
今天分享了Tomcat​的核心组件,然后讲解了Tomcat在处理请求时的三个核心参数和调优经验。对于maxThreads​参数,如果按照公式计算,我们需要获取IO时间和CPU时间,但实际上这两个值并不容易获取。maxThreads所以一般情况下,我们可以通过压测得到一个比较合适的。

对于提供接口服务的应用,很多都是使用SpringBoot​默认的Servlet​容器Tomcat​。上线之初,因为大部分流量较小,所以我们不会对Tomcat​做特别的参数调整。但是随着流量的增加,应用的性能指标越来越差。这个时候,我们大多数人都会选择扩容。除了扩容,我们还可以选择对Tomcat​进行性能调优,在不增加成本的情况下提升性能。今天我们就来分享一下如何对Tomcat进行简单的性能调优,提升应用性能。

Tomcat架构

图片

从上图可以看出,Tomcat​将自己的业务抽象成了Server​, Service​, Connector​, Container等组件,每个组件都有不同的作用。

Server​组件是Tomcat​的最外层组件,是Tomcat​实例本身的抽象,代表Tomcat本身。一个服务器组件可以有一个或多个服务组件。

Service​组件是Tomcat​中提供服务和处理请求的一组组件。一个服务组件可以有多个连接器和一个容器。Multiple Connector表示它可以使用多种协议同时接收用户请求。

Connector负责处理客户端连接,它提供各种服务协议的支持,包括BIO、NIO、AIO等,它存在的价值在于屏蔽了多协议Container的复杂性,统一了Container的处理标准。

Container​组件是负责具体业务逻辑处理的容器。当Connector​组件与客户端建立连接后,将请求转发给Container​组件的Engine组件进行处理。

至此,Tomcat​的核心组件就基本完成了。实际上,Container组件中还有很多细分的组件。其实如果对业务的抽象感兴趣,可以继续看下去。

  • Engine组件代表一个可运行的Servlet实例,包括Servlet容器的核心功能,可以有一个或多个虚拟主机(Host)。它的主要作用是将请求委托给合适的虚拟主机进行处理,即根据URL路径的配置匹配合适的虚拟主机进行处理。
  • Host组件负责运行多个应用程序,它负责安装这些应用程序。它的主要作用是解析web.xml文件,匹配到对应的Context组件。
  • Context组件代表了具体的Web应用本身,它最重要的作用就是管理里面的Servlet实例。一个 Context 可以有一个或多个 Servlet 实例。
  • 一个Wrapper组件代表一个Servlet,它负责管理一个Servlet,包括Servlet的加载、初始化、执行和资源回收。包装器是最低级别的容器。

可以看出Host是虚拟主机的抽象,Context是应用程序的抽象,Wrapper是Servlet的抽象,Engine是处理层的抽象。

Tomcat核心参数

在了解核心参数之前,我们需要对Tomcat对于请求的处理流程有一个大概的了解。Tomcat对请求的处理流程如下。

图片

在上面的示意图中,有3个非常关键的核心参数,也是性能调优的关键。

  • acceptCount​:当Container线程池达到最大数且没有空闲线程,Connector队列达到最大数时,操作系统可以接受的最大连接数。
  • maxConnections​:当Container线程池达到最大数量且没有空闲线程时,Connector的队列可以接收的最大线程数。
  • maxThreads:Container线程池的最大处理线程数。

从以上三个参数的含义,我们可以知道以下结论:

客户端并不直接与Tomcat的Connector​组件建立联系,而是先与操作系统建立联系,然后交给Connector​。这一点很重要,否则,你将看不懂acceptCount​参数。不仅Connector​组件中有一个队列,操作系统中也有一个队列来临时存放与客户端的连接,这也是一个关键点。我们所说的线程池是指Container容器中的线程池。

理解这三个核心参数的含义非常重要,否则就没有办法进行后续的性能调优工作。

最大线程数maxThreads

我们知道是maxThreads指最大请求处理线程数,Tomcat7和Tomcat8的默认值是200。

该参数的设置需要根据任务的执行内容进行调整。一般来说,计算公式为:maximum number of threads = ((IO time + CPU time)/CPU time) * number of CPU cores。

这个公式的思路其实很简单,就是最大化利用CPU资源。

任务的耗时分为IO耗时和CPU耗时。基本上IO时间消耗是最多的,此时CPU无事可做。所以如果在任务等待IO的时候可以让CPU去处理其他的任务,那么CPU的利用率就会提高。

一般来说,由于IO耗时远大于CPU耗时,maxThreads根据公式计算出来的个数会远大于CPU核数,这是正常的。

需要注意的是,这个值并不是越高越好。因为一旦线程过多,CPU就需要进行上下文切换,会消耗一部分CPU资源。

因此,最好的办法就是用上面的公式计算出一个基准值,然后进行压力测试,调整到一个合理的值。

一般来说,如果maxThreads增加了,但吞吐量没有增加或减少,则可能表明已经达到了瓶颈。

最大连接数maxConnections

maxConnections指的是当线程池中的线程达到最大值并且都处于忙碌状态时,Connector中的队列可以容纳的最大连接数。

一般来说,我们要设定一个合理的值,不能让它无限制地堆起来。

因为Tomcat的处理能力肯定是有限的,到了一定程度就肯定处理不了了。所以积累多了也没用。反而会造成内存堆积,最终导致内存溢出OOM。

一般来说,经验值可以设置为与maxThreads一样。我觉得这样比较合理,因为队列中的连接最多只需要等待线程处理一个任务,不会等待太久,响应时间也不会太长。

如果想缩短响应时间,可以maxConnections​调的比maxThreads小,这样可以减少一些响应时间。但需要注意的是,如果降得太低,性能可能会严重下降,吞吐量也会降低。

操作系统连接数acceptCount

acceptCount​是指Container​线程池达到最大数量且没有空闲线程,Connector队列达到最大数量时,操作系统可以接受的最大连接数。

当队列中的数量达到最大值时,将拒绝所有传入的请求。默认值为100。这可以理解为操作系统的一种自我保护机制。如果积累太多无法处理,那就拒绝它们以保护自己的资源。

该参数的调参资料比较少,但根据其含义,不建议该值大于maxConnections。

因为这个队列中的连接需要等待。如果这个值太大,意味着会有很多连接没有被处理。

连接越多,等待的时间越长,响应时间越慢。如果你想要更短的响应时间,你应该降低这个值。

acceptCount有的同学会疑惑,既然有,为什么还需要maxConnections?这不是重蹈覆辙吗?其实在BIO时代,这两个值基本一致。我猜是因为 , 以及后来其他技术的出现NIO,AIO操作系统可以接受更多的客户端连接。

因此,操作系统可以先建立一个连接缓存,然后Connector可以直接从操作系统获取连接,这样就不需要等待操作系统进行耗时的TCP连接,从而提高效率。

除了以上三个参数外,还有几个非核心参数,但我觉得还是有一定作用的。

  • connectionTimeout:连接建立后的等待超时时间。如果超过这个时间,则直接返回超时。
  • minSpareThreads:表示最小存活线程数,即如果没有请求,那么必须保持最小存活线程数。该参数与是否有突发流量有关。在突发流量的情况下,如果这个值太低,瞬时响应时间会比较长。

今天分享了Tomcat​的核心组件,然后讲解了Tomcat在处理请求时的三个核心参数和调优经验。

对于maxThreads​参数,如果按照公式计算,我们需要获取IO时间和CPU时间,但实际上这两个值并不容易获取。maxThreads所以一般情况下,我们可以通过压测得到一个比较合适的。

对于该maxConnections​参数,您可以设置一个与maxThreads相同的值,然后根据具体情况进行调整。

如果你想减少响应时间,你可以稍微调低它,否则你可以调高它。

对于acceptCount​参数,其调优逻辑类似maxConnections​,但不建议大于maxConnections,然后根据对应的时间要求进行微调。

责任编辑:武晓燕 来源: JAVA旭阳

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK