Tomcat性能调优

Tomcat性能调优

Tomcat9参数配置:Apache Tomcat 9 Configuration Reference (9.0.93) - The HTTP Connector

2.1 如何监控Tomcat的性能

Tomcat 的关键指标

Tomcat 的关键指标有吞吐量、响应时间、错误数、线程池、CPU 以及 JVM 内存。前三个指标是我们最关心的业务指标,Tomcat 作为服务器,就是要能够又快有好地处理请求,因此吞吐量要大、响应时间要短,并且错误数要少。后面三个指标是跟系统资源有关的,当某个资源出现瓶颈就会影响前面的业务指标,比如线程池中的线程数量不足会影响吞吐量和响应时间;但是线程数太多会耗费大量 CPU,也会影响吞吐量;当内存不足时会触发频繁地 GC,耗费 CPU,最后也会反映到业务指标上来。

通过 JConsole 监控 Tomcat3

JConsole是一款基于JMX的可视化监控和管理工具

1) 开启 JMX 的远程监听端口

我们可以在 Tomcat 的 bin 目录下新建一个名为setenv.sh的文件(或者setenv.bat,根据你的操作系统类型),然后输入下面的内容:

export JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote"
export JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.port=8011"
export JAVA_OPTS="${JAVA_OPTS} -Djava.rmi.server.hostname=x.x.x.x"
export JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.ssl=false"
export JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.authenticate=false"

2)重启 Tomcat,这样 JMX 的监听端口 8011 就开启了,接下来通过 JConsole 来连接这个端口。

jconsole x.x.x.x:8011

我们可以看到 JConsole 的主界面:

吞吐量、响应时间、错误数

在 MBeans 标签页下选择 GlobalRequestProcessor,这里有 Tomcat 请求处理的统计信息。你会看到 Tomcat 中的各种连接器,展开“http-nio-8080”,你会看到这个连接器上的统计信息,其中 maxTime 表示最长的响应时间,processingTime 表示平均响应时间,requestCount 表示吞吐量,errorCount 就是错误数。

线程池

选择“线程”标签页,可以看到当前 Tomcat 进程中有多少线程,如下图所示:

图的左下方是线程列表,右边是线程的运行栈,这些都是非常有用的信息。如果大量线程阻塞,通过观察线程栈,能看到线程阻塞在哪个函数,有可能是 I/O 等待,或者是死锁。      

CPU

在主界面可以找到 CPU 使用率指标,请注意这里的 CPU 使用率指的是 Tomcat 进程占用的 CPU,不是主机总的 CPU 使用率。

JVM 内存

选择“内存”标签页,你能看到 Tomcat 进程的 JVM 内存使用情况。

命令行查看 Tomcat 指标

极端情况下如果 Web 应用占用过多 CPU 或者内存,又或者程序中发生了死锁,导致 Web 应用对外没有响应,监控系统上看不到数据,这个时候需要我们登陆到目标机器,通过命令行来查看各种指标。

1. 首先我们通过 ps 命令找到 Tomcat 进程,拿到进程 ID。

ps -ef|grep tomcat

2. 接着查看进程状态的大致信息,通过cat /proc//status命令:

3. 监控进程的 CPU 和内存资源使用情况:

4. 查看 Tomcat 的网络连接,比如 Tomcat 在 8080 端口上监听连接请求,通过下面的命令查看连接列表:

你还可以分别统计处在“已连接”状态和“TIME_WAIT”状态的连接数:

5. 通过 ifstat 来查看网络流量,大致可以看出 Tomcat 当前的请求数和负载状况。

2.2 线程池的并发调优

线程池调优指的是给 Tomcat 的线程池设置合适的参数,使得 Tomcat 能够又快又好地处理请求。

sever.xml中配置线程池

<!--
namePrefix: 线程前缀
maxThreads: 最大线程数,默认设置 200,一般建议在 500 ~ 1000,根据硬件设施和业务来判断
minSpareThreads: 核心线程数,默认设置 25
prestartminSpareThreads: 在 Tomcat 初始化的时候就初始化核心线程
maxQueueSize: 最大的等待队列数,超过则拒绝请求 ,默认 Integer.MAX_VALUE
maxIdleTime: 线程空闲时间,超过该时间,线程会被销毁,单位毫秒
className: 线程实现类,默认org.apache.catalina.core.StandardThreadExecutor
-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-Fox"
          prestartminSpareThreads="true"
          maxThreads="500" minSpareThreads="10"  maxIdleTime="10000"/>
          
<Connector port="8080" protocol="HTTP/1.1"  executor="tomcatThreadPool"
           connectionTimeout="20000"
           redirectPort="8443" URIEncoding="UTF-8"/>

这里面最核心的就是如何确定 maxThreads 的值,如果这个参数设置小了,Tomcat 会发生线程饥饿,并且请求的处理会在队列中排队等待,导致响应时间变长;如果 maxThreads 参数值过大,同样也会有问题,因为服务器的 CPU 的核数有限,线程数太多会导致线程在 CPU 上来回切换,耗费大量的切换开销。

理论上我们可以通过公式 线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间),计算出一个理想值,这个值只具有指导意义,因为它受到各种资源的限制,实际场景中,我们需要在理想值的基础上进行压测,来获得最佳线程数。

SpringBoot中调整Tomcat参数

方式1: yml中配置 (属性配置类:ServerProperties)

server:
  tomcat:
    threads:
      min-spare: 20
      max: 500
    connection-timeout: 5000ms

SpringBoot中的TomcatConnectorCustomizer类可用于对Connector进行定制化修改。

@Configuration
public class MyTomcatCustomizer implements
        WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.setPort(8090);
        factory.setProtocol("org.apache.coyote.http11.Http11NioProtocol");
        factory.addConnectorCustomizers(connectorCustomizer());
    }

    @Bean
    public TomcatConnectorCustomizer connectorCustomizer(){
        return new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
                protocol.setMaxThreads(500);
                protocol.setMinSpareThreads(20);
                protocol.setConnectionTimeout(5000);
            }
        };
    }

}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿立聊代码

有作用的,有闲钱的支持一点。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值