Tomcat 线程模型性能调优

Linux I/O模型详解

I/O要解决什么问题

I/O:在计算机内存与外部设备之间拷贝数据的过程。

程序通过CPU向外部设备发出读指令,数据从外部设备拷贝至内存需要一段时间,这段时间CPU就没事情做了,程序就会两种选择:

  1. 让出CPU资源,让其干其他事情

  2. 继续让CPU不停地查询数据是否拷贝完成

到底采取何种选择就是I/O模型需要解决的事情了。

以网络数据读取为例来分析,会涉及两个对象,一个是调用这个I/O操作的用户线程,另一个是操作系统内核。一个进程的地址空间分为用户空间和内核空间,基于安全上的考虑,用户程序只能访问用户空间,内核程序可以访问整个进程空间,只有内核可以直接访问各种硬件资源,比如磁盘和网卡。

在这里插入图片描述

当用户线程发起 I/O 调用后,网络数据读取操作会经历两个步骤:

  • 数据准备阶段: 用户线程等待内核将数据从网卡拷贝到内核空间。
  • 数据拷贝阶段: 内核将数据从内核空间拷贝到用户空间(应用进程的缓冲区)。

Linux的I/O模型分类

Linux 系统下的 I/O 模型有 5 种:

  1. 同步阻塞I/O(bloking I/O)
  2. 同步非阻塞I/O(non-blocking I/O)
  3. I/O多路复用(multiplexing I/O)
  4. 信号驱动式I/O(signal-driven I/O)
  5. 异步I/O(asynchronous I/O)

其中信号驱动式IO在实际中并不常用

阻塞或非阻塞是指应用程序在发起 I/O 操作时,是立即返回还是等待。

同步或异步是指应用程序在与内核通信时,数据从内核空间到应用空间的拷贝,是由内核主动发起还是由应用程序来触发


  1. BIO,一个请求来会阻塞,需要使用线程池来管理使得每个线程监听一个客户端,否则服务端一次只能控制一个客户端
  2. NIO,普通版nio建立连接以后不会阻塞,而是把所有连接放在一个数组,每次都需要自行遍历所有数组来查找是否有新消息输入,效率低
  3. 带有多路复用的NIO,多了一个selector,selector会监听所有的通道,不需要像前两种一样while(true)来轮训
  4. AIO,类似于多线程的异步调用,需要使用回调函数

Tomcat I/O 模型如何选型

I/O 调优实际上是连接器类型的选择,一般情况下默认都是 NIO,在绝大多数情况下都是够用的,除非你的 Web 应用用到了 TLS 加密传输,而且对性能要求极高,这个时候可以考虑 APR,因为 APR通过 OpenSSL 来处理 TLS 握手和加密 / 解密。OpenSSL 本身用 C 语言实现,它还对 TLS 通信做了优化,所以性能比 Java 要高。如果你的 Tomcat 跑在 Windows 平台上,并且 HTTP 请求的数据量比 较大,可以考虑 NIO2,这是因为 Windows 从操作系统层面实现了真正意义上的异步 I/O,如果传输的数据量比较大,异步 I/O 的效果就能显现出来。如果你的 Tomcat 跑在 Linux 平台上,建议使用NIO。因为在 Linux 平台上,Java NIO 和 Java NIO2 底层都是通过 epoll 来实现的,但是 Java NIO更加简单高效。

指定IO模型只需修改protocol配置

<!-- 修改protocol属性, 使用NIO2 --> <Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443" /> 

网络编程模型Reactor线程模型

Reactor 模型是网络服务器端用来处理高并发网络 IO 请求的一种编程模型。

该模型主要有三类处理事件:即连接事件、写事件、读事件;三个关键角色:即 reactor、acceptor、 handler。acceptor负责连接事件,handler负责读写事件,reactor负责事件监听和事件分发。

单 Reactor 单线程

在这里插入图片描述

由上图可以看出,单Reactor单线程模型中的 reactor、acceptor 和 handler以及后续业务处理逻辑的

功能都是由一个线程来执行的。reactor 负责监听客户端事件和事件分发,一旦有连接事件发生,它会

分发给 acceptor,由 acceptor 负责建立连接,然后创建一个 handler。如果是读写事件,reactor 将

事件分发给 handler 进行处理。handler 负责读取客户端请求,进行业务处理,并最终给客户端返回

结果。


单 Reactor 多线程

在这里插入图片描述

该模型中,reactor、acceptor 和 handler 的功能由一个线程来执行,与此同时,会有一个线程池,

由若干 worker 线程组成。在监听客户端事件、连接事件处理方面,这个类型和单 rector 单线程是相

同的,但是不同之处在于,在单 reactor 多线程类型中,handler 只负责读取请求和写回结果,而具

体的业务处理由 worker 线程来完成。

主从 Reactor 多线程

在这里插入图片描述

在这个类型中,会有一个主 reactor 线程、多个子 reactor 线程和多个 worker 线程组成的一个线程

池。其中,主 reactor 负责监听客户端事件,并在同一个线程中让 acceptor 处理连接事件。一旦连接

建立后,主 reactor 会把连接分发给子 reactor 线程,由子 reactor 负责这个连接上的后续事件处

理。那么,子 reactor 会监听客户端连接上的后续事件,有读写事件发生时,它会让在同一个线程中

的 handler 读取请求和返回结果,而和单 reactor 多线程类似,具体业务处理,它还是会让线程池中

的 worker 线程处理。

Tomcat NIO实现

**Tomcat NIO实现

在 Tomcat 中,EndPoint 组件的主要工作就是处理 I/O,而 NioEndpoint 利用 Java NIO API 实现了

多路复用 I/O 模型。Tomcat的NioEndpoint 是基于主从Reactor多线程模型设计的

在这里插入图片描述

  • LimitLatch 是连接控制器,它负责控制最大连接数,NIO 模式下默认是 10000(tomcat9中8192),当连接数到达最大时阻塞线程,直到后续组件处理完一个连接后将连接数减 1。注意到达最大连接数后操作系统底层还是会接收客户端连接,但用户层已经不再接收。
  • Acceptor 跑在一个单独的线程里,它在一个死循环里调用 accept 方法来接收新连接,一旦有新的连接请求到来,accept 方法返回一个 Channel 对象,接着把 Channel 对象交给 Poller 去处理。
  • Poller 的本质是一个 Selector,也跑在单独线程里。Poller 在内部维护一个 Channel 数组,它在一个死循环里不断检测 Channel 的数据就绪状态,一旦有 Channel 可读,就生成一个 SocketProcessor 任务对象扔给Executor 去处理。
  • Executor 就是线程池,负责运行 SocketProcessor 任务类,SocketProcessor 的 run 方法会调Http11Processor 来读取和解析请求数据。Http11Processor 是应用层协议的封装,它会调用容器获得响应,再把响应通过Channel 写出。

Tomcat 异步IO实现

NIO 和 NIO2 最大的区别是,一个是同步一个是异步。异步最大的特点是,应用程序不需要自己去触发数据从内核空间到用户空间的拷贝。

在这里插入图片描述

Nio2Endpoint 中没有 Poller 组件,也就是没有 Selector。在异步 I/O 模式下,Selector 的工作交给内核来做了。

Tomcat性能调优

Tomcat 的关键指标

Tomcat 的关键指标有吞吐量、响应时间、错误数、线程池、CPU 以及 JVM 内存。前三个指标是

我们最关心的业务指标,Tomcat 作为服务器,就是要能够又快有好地处理请求,因此吞吐量要大、响

应时间要短,并且错误数要少。后面三个指标是跟系统资源有关的,当某个资源出现瓶颈就会影响前

面的业务指标,比如线程池中的线程数量不足会影响吞吐量和响应时间;但是线程数太多会耗费大量

CPU,也会影响吞吐量;当内存不足时会触发频繁地 GC,耗费 CPU,最后也会反映到业务指标上

来。


通过 JConsole 监控 Tomcat

  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

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

在这里插入图片描述

线程池的并发调优

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

sever.xml中配置线程池

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

这里面最核心的就是如何确定 maxThreads 的值,如果这个参数设置小了,Tomcat 会发生线程饥

饿,并且请求的处理会在队列中排队等待,导致响应时间变长;如果 maxThreads 参数值过大,同样

也会有问题,因为服务器的 CPU 的核数有限,线程数太多会导致线程在 CPU 上来回切换,耗费大量

的切换开销。

理论上我们可以通过公式 线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间),计算出一

个理想值,这个值只具有指导意义,因为它受到各种资源的限制,实际场景中,我们需要在理想值的

基础上进行压测,来获得最佳线程数。

SpringBoot中调整Tomcat参数

yml中配置 (属性配置类:ServerProperties)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/102284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

四款数字办公工具大比拼,在线办公无压力

在线办公软件使企业、员工实现办公场所、距离的自由&#xff0c;尤其是近几年&#xff0c;受“口罩”的影响&#xff0c;远程办公软件的使用者也越来越多&#xff0c;无论是财务、行政、还是设计师&#xff0c;都开始追求好用的在线办公软件&#xff0c;作为办公软件发烧友&…

C++11新特性(右值引用,万能转发)

这篇文章是C的重中之重&#xff0c;通过这篇文章你能体会到C/C大佬们对性能的极致追求&#xff0c;你能感受到独属C/C人的浪漫&#xff0c;对高消耗的零容忍&#xff0c;对高性能的不倦探索。右值引用是由Scott Meyers在他的著名书籍《Effective C》中提出的&#xff0c;因为其…

webservice接口自动化测试

1&#xff0c;用soupui进行测试 2&#xff0c;安装soupUI 3&#xff0c;测试的时候是给了一个wdsl 操作步诹&#xff1a;new &#xff08;name , 填写地址&#xff09;---导入wsdl文件---看到所有的接口 发送请求的格式<xml> canshu</xml> 应用场景&#xff0c…

hutool实现文件上传与下载

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> 文件上传需要创建一个表 Autowiredprivate SysFileInfoMapper sysFileInfoMapper;Value("${ty.…

常用的语音芯片工作原理_分类为语音播报 语音识别 语音合成tts

1.0 语音芯片分类-语音播报-语音识别-语音合成 关于声音的需求&#xff0c;从始至终&#xff0c;都是很刚需的需求 。从语音芯片的演化就能看出很多的端倪&#xff0c;很多很多的产品他必须要有语音&#xff0c;才能实现更好的交互。而语音芯片的需求分类&#xff0c;其实也是很…

3D模型格式转换工具HOOPS Exchange:模型数据自由导入和导出

HOOPS Exchange是一套高性能软件库&#xff0c;可以为软件开发人员提供导入和导出3D文件格式的能力。HOOPS Exchange导入3D数据后&#xff0c;会将3D数据转换为PRC格式存放到内存中&#xff0c;最后导出成为其他3D格式。&#xff08;点击申请HOOPS Exchange免费试用&#xff09…

人大金仓数据库V8 windows下安装

此文为人大金仓数据库安装程序&#xff08;windows下kingbase开发及测试用&#xff09;。 1 人大金仓-成为世界卓越的数据库产品与服务提供商 官方下载安装包&#xff0c;同时需要下载授权文件&#xff0c;补丁文件可以不下。 2 点击安装 3 选择授权文件 4 默认安装即可&…

Docker 容器应急

容器网络简单理解 容器拥有n多张veth网卡与一张docker0网卡 docker 五种网络 bridge 默认网络&#xff0c;Docker启动后创建一个docker0网桥&#xff0c;默认创建的容器也是添加到这个网桥中。host 容器不会获得一个独立的network namespace&#xff0c;而是与宿主机共用一个…

统一机器人描述格式——URDF

URDF&#xff08;Unified Robot Description Format&#xff0c;统一机器人描述格式&#xff09;是ROS中一个非常重要的机器人模型描述格式&#xff0c;ROS同时也提供URDF文件的C解析器&#xff0c;可以解析URDF文件中使用XML格式描述的机器人模型。 在使用URDF文件构建机器人模…

【LeetCode力扣】75 快速排序的子过程partition(荷兰国旗问题)

目录 1、题目介绍 2、解题思路 2.1、冒泡排序暴力破解 2.2、快速排序的子过程partition 2.2.1、详细过程描述 2.2.2、代码描述 1、题目介绍 原题链接&#xff1a;75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; 示例 1&#xff1a; 输入&#xff1a;nums [2,0,2…

【Python深度学习】目标检测和语义分割的区别

在计算机视觉领域&#xff0c;语义分割和目标检测是两个关键的任务&#xff0c;它们都是对图像和视频进行分析&#xff0c;但它们之间存在着明显的区别。本文将通过图像示例&#xff0c;详细阐述语义分割和目标检测之间的差异。 一、基本概念 1.1 语义分割&#xff08;Semantic…

升级MacOS后无法打开 Parallels Desktop,提示“要完成 Parallels Desktop 设置,请重新启动 Mac 。”

有用户升级macOS后&#xff0c;发现无法打开PD虚拟机了&#xff0c;提示“要完成 Parallels Desktop 设置&#xff0c;请重新启动 Mac 。”但是重启电脑之后&#xff0c;尝试了卸载重装&#xff0c;安装新版本&#xff0c;都无法解决问题&#xff0c;打开依旧如此提示&#xff…

C#关于接口的常见面试问题

1.1 关于C#接口的问题以及与抽象类的异同 什么是接口 继承有几种形式 为什么要使用接口&#xff1f; 接口类型可以用public关键字修饰吗&#xff1f; 接口能不能派生于抽象类&#xff1f; 接口能不能用Sealed修饰&#xff1f; 一个类可以继承多个接口吗&#xff1f; 必…

TSINGSEE青犀视频AI分析/边缘计算/AI算法·厨师帽检测功能——多场景高效运用

在餐饮厂房等场景中&#xff0c;为保障食品安全与卫生&#xff0c;后厨操作人员规范着装要求是必不可少的。由于后厨温度较高&#xff0c;环境较为恶劣&#xff0c;很多后厨人员为自身方便不按照规定佩戴厨师帽和着厨师服&#xff0c;为切实解决此问题&#xff0c;TSINGSEE青犀…

【FreeRTOS】【STM32】03 FreeRTOSConfig.h头文件简介与修改

基于[野火]《FreeRTOS%20内核实现与应用开发实战—基于STM32》.pdf FreeRTOSConfig.h头文件是FreeRTOS各项功能的打开与关闭 FreeRTOSConfig.h头文件简介 之前也说过了&#xff0c;FreeRTOSConfig.h文件可以添加在工程中任意文件夹&#xff0c;只需要在路径中添加好了就行。…

【C++初阶】前言——C++的发展简述及学习方法分享

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法&#xff1a;算法专栏 C头…

取消加考!自考专业调整,2026年起执行新计划!

就在2023年10月7日&#xff0c;广东省教育考试院发布《关于广东省高等教育自学考试专业调整有关事项的通知》&#xff0c;自学考试迎来新变化&#xff0c;本次专业调整政策性强&#xff0c;涉及面广&#xff0c;持续时间长&#xff0c;一起来看看具体说明~ 关于广东省高等教育自…

【码银送书第八期】《Python数据挖掘:入门进阶与实用案例分析》

摘要&#xff1a;本案例将主要结合自动售货机的实际情况&#xff0c;对销售的历史数据进行处理&#xff0c;利用pyecharts库、Matplotlib库进行可视化分析&#xff0c;并对未来4周商品的销售额进行预测&#xff0c;从而为企业制定相应的自动售货机市场需求分析及销售建议提供参…

模拟大数相加

字符串的大数相加&#xff0c;不可以直接使用stoi&#xff0c;或者stoll这种函数去相加&#xff0c;随时有可能越界。只需要模拟计算加法的过程就可以了。 1.定义两个尾指针&#xff0c;指向num1,nums2的最后一个数字&#xff0c;让这两个数字相加&#xff0c;并把相加的结果记…

易点易动设备管理系统:打通采购管理的智能化设备管理解决方案

在现代企业的运营中&#xff0c;设备管理是一个关键的环节。传统的设备管理方法往往效率低下&#xff0c;导致设备故障频发、巡检和维修工作不协调&#xff0c;备件管理不规范。为了解决这些问题&#xff0c;我们引入了易点易动设备管理系统&#xff0c;它能够全面管理设备的生…