Tomcat基础升华学习

01 What is Tomcat

1.1 Tomcat官网

官网 :https://tomcat.apache.org

1.2 Understand

为什么说Tomcat是Servlet之类技术的实现?
在我们的理解中,Tomcat可以称为Web容器或者Servlet容器
不妨通过手写一个Tomcat来推导一下

1.2.1 创建Tomcat类

Java是一门面向对象的开发语言

//这就是我们写的Tomcat
class MyTomcat{
....
}
1.2.2 Web容器

在这里插入图片描述
在这里插入图片描述
使用命令查看相关指标

01 查看tomcat进程pid
ps -ef | grep tomcat
02 查看进程的信息
cat /pro/pid/status
03 查看进程的cpu和内存
top -p pid

使用工具查看相关指标

jconsole、jvisualvm、arthas、psi-probe等

1.1 优化思路

1.1.1 conf/server.xml核心组件

Server
官网描述 :Server interface which is rarely customized by users. 【pass】
Service
官网描述 :The Service element is rarely customized by users. 【pass】
Connector
官网描述 :Creating a customized connector is a significant effort. 【 need 】
Engine
官网描述 :The Engine interface may be implemented to supply custom Engines, though this is uncommon.
【pass】
Host
官网描述 :Users rarely create custom Hosts because the StandardHost implementation provides significant
additional functionality. 【pass】
Context
官网描述 :The Context interface may be implemented to create custom Contexts, but this is rarely the case
because the StandardContext provides significant additional functionality. 【 maybe 】
Context既然代表的是web应用,是和我们比较接近的,这块我们考虑对其适当的优化
conclusion:Connector and Context

1.1.2 conf/server.xml非核心组件

官网 :https://tomcat.apache.org/tomcat-8.0-doc/config/index.html
Listener
Listener(即监听器)定义的组件,可以在特定事件发生时执行特定的操作;被监听的事件通常是Tomcat的启动和停止。

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--监听内存溢出-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

Global Resources
GlobalNamingResources元素定义了全局资源,通过配置可以看出,该配置是通过读取$TOMCAT_HOME/
conf/tomcat-users.xml实现的。
The GlobalNamingResources element defines the global JNDI resources for the [Server]
(https://tomcat.apache.org/tomcat-8.0-doc/config/server.html)

<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>

Valve

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

Realm
Realm,可以把它理解成“域”;Realm提供了一种用户密码与web应用的映射关系,从而达到角色安全管理的作用。在本例
中,Realm的配置使用name为UserDatabase的资源实现。而该资源在Server元素中使用GlobalNamingResources配置
A Realm element represents a “database” of usernames, passwords, and roles (similar to
Unix groups) assigned to those users.

<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
1.1.3 conf/web.xml

全局的web.xml文件有些标签用不到的,可以删除掉。

1.1.4 JVM层面

因为Tomcat运行起来本身就是一个Java进程,所以这块可以参照JVM部分的优化思路。

1.2 配置优化

1.2.1 减少web.xml/server.xml中标签

最终观察tomcat启动日志[时间/内容],线程开销,内存大小,GC等
DefaultServlet
官网 :User Guide->Default Servlet
The default servlet is the servlet which serves static resources as well as serves the directory listings (if
directory listings are enabled)

<servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

JspServlet

<servlet><servlet-name>jsp</servlet-name><servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class><init-param><param-name>fork</param-name><param-value>false</param-value></init-param><init-param><param-name>xpoweredBy</param-name><param-value>false</param-value></init-param><load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>*.jsp</url-pattern><url-pattern>*.jspx</url-pattern>
</servlet-mapping>

welcome-list-file

<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file>
</welcome-file-list>

mime-mapping移除响应的内容
支持的下载打开类型

<mime-mapping><extension>123</extension><mime-type>application/vnd.lotus-1-2-3</mime-type>
</mime-mapping>
<mime-mapping><extension>3dml</extension><mime-type>text/vnd.in3d.3dml</mime-type>
</mime-mapping>

session-config
默认jsp页面有session,就是在于这个配置

<session-config><session-timeout>30</session-timeout>
</session-config>
1.2.2 调整优化server.xml中标签
1.2.2.1 Connector标签

protocol属性

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

对于protocol=“HTTP/1.1”,查看源码
构造函数

public Connector(String protocol) {
setProtocol(protocol);
}

setProtocol(protocol)因为配置文件中传入的是HTTP/1.1
并且这里没有使用APR

else {if ("HTTP/1.1".equals(protocol)) {setProtocolHandlerClassName("org.apache.coyote.http11.Http11NioProtocol");} else if ("AJP/1.3".equals(protocol)) {setProtocolHandlerClassName("org.apache.coyote.ajp.AjpNioProtocol");} else if (protocol != null) {setProtocolHandlerClassName(protocol);}
}

发现这里调用的是Http11NioProtocol,也就是说明tomcat8.0.x中默认使用的是NIO
使用同样的方式看tomcat7和tomcat8.5,你会发现tomcat7默认使用的是BIO,tomcat8.5默认使用的是NIO
针对BIO和NIO的方式进行压测
(1)BIO
来到tomcat官网Configuration/HTTP/protocol

org.apache.coyote.http11.Http11Protocol - blocking Java connector
org.apache.coyote.http11.Http11NioProtocol - non blocking Java NIO connector
org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java NIO2 connector
org.apache.coyote.http11.Http11AprProtocol - the APR/native connector.

(2)NIO
tomcat8.0中默认使用的是NIO
(3)APR
调用本地方法库进行IO操作
executor属性
最佳线程数公式 😦(线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

The Executor represents a thread pool that can be shared between components in Tomcat.
Historically there has been a thread pool per connector created but this allows you to
share a thread pool, between (primarily) connector but also other components when those get
configured to support executors

默认的可以查看StandardExecutor类
设置一些属性
官网:https://tomcat.apache.org/tomcat-8.0-doc/config/http.html
(1)acceptCount:达到最大连接数之后,等待队列中还能放多少连接,超过即拒绝,配置太大也没有意义

The maximum queue length for incoming connection requests when all possible request
processing threads are in use. Any requests received when the queue is full will be
refused. The default value is 100.

(2)maxConnections
达到这个值之后,将继续接受连接,但是不处理,能继续接受多少根据acceptCount的值
BIO:maxThreads
NIO/NIO2:10000 ——— AbstractEndpoint.maxConnections
APR:8192

The maximum number of connections that the server will accept and process at any given
time. When this number has been reached, the server will accept, but not process, one
further connection. This additional connection be blocked until the number of connections
being processed falls below maxConnections at which point the server will start accepting
and processing new connections again. Note that once the limit has been reached, the
operating system may still accept connections based on the acceptCount setting. The default
value varies by connector type. For BIO the default is the value of maxThreads unless an
Executor is used in which case the default will be the value of maxThreads from the
executor. For NIO and NIO2 the default is 10000. For APR/native, the default is 8192.
Note that for APR/native on Windows, the configured value will be reduced to the highest
multiple of 1024 that is less than or equal to maxConnections. This is done for performance
reasons.
If set to a value of -1, the maxConnections feature is disabled and connections are not
counted.

(3)maxThreads:最大工作线程数,也就是用来处理request请求的,默认是200,如果自己配了executor,并且和
Connector有关联了,则之前默认的200就会被忽略,取决于CPU的配置。监控中就可以看到所有的工作线程是什么
状态,通过监控就能知道开启多少个线程合适.

The maximum number of request processing threads to be created by this Connector, which
therefore determines the maximum number of simultaneous requests that can be handled. If
not specified, this attribute is set to 200. If an executor is associated with this
connector, this attribute is ignored as the connector will execute tasks using the executor
rather than an internal thread pool. Note that if an executor is configured any value set
for this attribute will be recorded correctly but it will be reported (e.g. via JMX) as -1
to make clear that it is not used.

(4)minSpareThreads
最小空闲线程数

The minimum number of threads always kept running. This includes both active and idle
threads. If not specified, the default of 10 is used. If an executor is associated with
this connector, this attribute is ignored as the connector will execute tasks using the
executor rather than an internal thread pool. Note that if an executor is configured any
value set for this attribute will be recorded correctly but it will be reported (e.g. via
JMX) as -1 to make clear that it is not used.

可以实践一下,Connector配合自定义的线程池

<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>

其实这块最好的方式是结合BIO来看,因为BIO是一个request对应一个线程
值太低,并发请求多了之后,多余的则进入等待状态。
值太高,启动Tomcat将花费更多的时间。
比如可以改成250。
enableLookups
设置为false
删掉AJP的Connector

1.2.2.2 Host标签

autoDeploy :Tomcat运行时,要用一个线程拿出来进行检查,生产环境之下一定要改成false

This flag value indicates if Tomcat should check periodically for new or updated web
applications while Tomcat is running. If true, Tomcat periodically checks the appBase and
xmlBase directories and deploys any new web applications or context XML descriptors found.
Updated web applications or context XML descriptors will trigger a reload of the web
application. The flag's value defaults to true. See Automatic Application Deployment for
more information.
1.2.2.3 Context标签

reloadable:false
reloadable:如果这个属性设为true,tomcat服务器在运行状态下会监视在WEB-INF/classes和WEB-INF/lib目录下
class文件的改动,如果监测到有class文件被更新的,服务器会自动重新加载Web应用。
在开发阶段将reloadable属性设为true,有助于调试servlet和其它的class文件,但这样用加重服务器运行负荷,建议
在Web应用的发存阶段将reloadable设为false。

Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib
for changes, and automatically reload the web application if a change is detected. This
feature is very useful during application development, but it requires significant runtime
overhead and is not recommended for use on deployed production applications. That's why the
default setting for this attribute is false. You can use the Manager web application,
however, to trigger reloads of deployed applications on demand.

1.3 启动速度优化

删除没用的web应用
因为tomcat启动每次都会部署这些应用
关闭WebSocket
websocket-api.jar和tomcat-websocket.jar
随机数优化
设置JVM参数:-Djava.security.egd=file:/dev/./urandom
多个线程启动Web应用

<Host startStopThreads="0">
</Host>

1.4 其他方面的优化

Connector
配置压缩属性compression=“500”,文件大于500bytes才会压缩
数据库优化
减少对数据库访问等待的时间,可以从数据库的层面进行优化,或者加缓存等等各种方案。
开启浏览器缓存,nginx静态资源部署

1.5 常见问题排查

1.5.1 CPU使用率过高

可能原因
GC频繁或者创建了很多业务线程
排查
哪些线程比较消耗CPU,或者多线程上下文频繁切换
解决思路
top -H -p pid 查看某个Java进程各个线程使用CPU的情况,找到哪个线程占用CPU比较高
jstack pid 打印出线程信息,定位到上述的线程名称

1.5.2 拒绝连接

java.net.BindException: Address already in use: JVM_Bind
端口被占用,可以使用netstat -an 查看端口占用情况,关闭对应的进程或者tomcat换端口
java.net.ConnectException: Connection refused: connect
ping一下服务端的IP,可能服务端机器有问题
java.net.SocketException: Too many open files
可能在高并发的情况下,创建的Socket过多,文件句柄不够用了,可以关闭无用的句柄,如果都有用,可以增加文件
句柄数:ulimit -n 10000

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

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

相关文章

androj studio安装及运行源码

抖音教学视频 目录 1、 jdk安装 2、下载安装androj studio 3 、打开源码安装运行相关组件 4、 安装模拟器 1、 jdk安装 安卓项目也是java开发的&#xff0c;运行在虚拟机上&#xff0c;安装jdk及运行的时候&#xff0c;就会自动生成虚拟机&#xff0c; jdk前面已经讲过&…

测试八年|对业务测试人员的一些思考

自从事测试工作八年多以来&#xff0c;经历过三个部门多条业务线&#xff0c;也经历过测试转型再回到测试&#xff0c;在此过程中对测试工作和角色的认知也逐步有些思考&#xff0c;想把这些思考分享给大家&#xff0c;希望为业务测试同学提供一些有价值的思路。 一、质量保障…

Java封装了一个自适应的单位转换工具类

目录 前言 1、前期准备 2、实现代码 2.1 方法一&#xff1a;通过map去标记需要转换的 类属性字段 2.2 方法二&#xff1a;配合自定义注解 前言 平时在做项目中&#xff0c;经常会做一些数据书籍&#xff0c;尤其像是数据看板之类&#xff0c;需要从数据库中查询想要的数据…

评论转换输出 - 华为OD统一考试

OD统一考试 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 在一个博客网站上&#xff0c;每篇博客都有评论。每一条评论都是一个非空英文字母字符串。 评论具有树状结构&#xff0c;除了根评论外&#xff0c;每个评论都有一个父评论。当评论保存时&am…

环信服务端下载消息文件---菜鸟教程

前言 在服务端&#xff0c;下载消息文件是一个重要的功能。它允许您从服务器端获取并保存聊天消息、文件等数据&#xff0c;以便在本地进行进一步的处理和分析。本指南将指导您完成环信服务端下载消息文件的步骤。 环信服务端下载消息文件是指在环信服务端上&#xff0c;通过调…

重学Java 1.学习路线及相关概述

别灰心&#xff0c;好运会降临 ——24.1.11 Ss.1 学习框架图 Ss.2 硬件和软件 硬件是看得见、摸得着的物理部件或设备 软件是以程序和文档的形式存在 硬件和软件是相辅相成的&#xff0c;谁也离不开谁 Ss.3 计算机语言 计算机编程语言&#xff0c;就是人们对计算机下达的命令&a…

Linux集锦大全【持续更新】

文章目录 Linux集锦大全【持续更新】Linux最常用的几个归档和压缩命令解压方法之一 tar语法压缩文件查看压缩文件的内容解压文件 解压方法之一 zip语法参数参考实例仅保存文件名 解压命令之一 unzip基本命令指定目录解压不解压某些文件 解压命令之一 gzip Linux最危险的几个命令…

OpenGL学习笔记-Blending

混合方程中&#xff0c;Csource是片段着色器输出的颜色向量&#xff08;the color output of the fragment shader&#xff09;&#xff0c;其权重为Fsource。Cdestination是当前存储在color buffer中的颜色向量&#xff08;the color vector that is currently stored in the …

NAND Separate Command Address (SCA) 接口命令解读

CA output packet和CA input packet是Separate Command Address (SCA) NAND接口协议中用于命令和地址传输的关键数据结构。 CA Input Packet: 在SCA接口中&#xff0c;输入到NAND器件的命令和地址信息被组织成并行至串行转换的CA&#xff08;Command and Address&#xff09;输…

List列表操作中的坑

使用 Arrays.asList 把数据转换为 List 的三个坑 在如下代码中&#xff0c;我们初始化三个数字的 int[]数组&#xff0c;然后使用 Arrays.asList 把数组转换为 List&#xff1a; int[] arr {1, 2, 3}; List list Arrays.asList(arr); log.info("list:{} size:{} class…

服务器应用相关代码

1&#xff1a;建立基本网络服务器 我们的ESP866-NodeMCU虽然也能实现网络服务器的一些功能&#xff0c;但是毕竟它的运算能力是无法与那些昂贵的服务器电脑相媲美的&#xff0c;因此ESP8266-NodeMCU只能实现一些基本的网络服务功能。网络服务是一个很宽泛的概念&#xff0c;我…

HCIA的交换机(单臂路由)

实现单臂路由的IP自动分配 实验素材&#xff1a; 实现思路&#xff1a; 交换机&#xff1a;创建VLAN10&#xff0c;VLAN20&#xff0c;将0/0/1&#xff0c;2划入相应VLAN&#xff0c;接口使用access模式&#xff0c; 要实现两个交换机之间的通信&#xff0c;须在0/0/3口使用t…

MC-4/11/01/400具有精度高一倍和低速运行时振动较小的优点

MC-4/11/01/400具有精度高一倍和低速运行时振动较小的优点 MC-4/11/01/400具有精度高一倍和低速运行时振动较小的优点 整步驱动模式&#xff1a;在整步驱动模式中&#xff0c;步进电机控制器按照脉冲方向指令对两相步进电机的两个线圈进行循环激磁。每个脉冲会使电机移动一个…

知乎x-zse-96算法分析

声明 本文以教学为基准、本文提供的可操作性不得用于任何商业用途和违法违规场景。 本人对任何原因在使用本人中提供的代码和策略时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。 如有侵权,请联系我进行删除。 这里只是我分析过程,以及一些重要点的记录,没有…

YOLOv5改进系列(25)——添加LSKNet注意力机制(大选择性卷积核的领域首次探索)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制 YOLOv5改进系

ES高级查询

ES中提供了一种强大的检索数据方式&#xff0c;这种检索方式称为Query DSL&#xff0c;这种方式的丰富查询语法让ES检索变得更强大&#xff0c;更简洁。 1.常见查询 1.1查询所有[match_all] match_all关键字&#xff1a;返回索引中的全部文档。 GET /products/_search { &…

【MFC实践】基于MFC向导C++制作计算器(附文件)

一、写在前面1.1 什么是MFC向导&#xff1f;1.2 使用MFC向导制作计算器1.3安装visual studio 2022和MFC插件 二、设计计算器界面1.1 新创建MFC项目1.2 设计计算器界面1.3 添加相关变量1.4 算法的一些问题及解决方式1.5 计算功能的实现1.6 其它功能的实现1.6.1 DEL功能1.6.2 C置…

关于白盒测试,这些技巧你得游刃有余~

对于很多刚开始学习软件测试的小伙伴来说&#xff0c;如果能尽早将黑盒、白盒测试弄明白&#xff0c;掌握两种测试的结论和基本原理&#xff0c;将对自己后期的学习有较好的帮助。今天&#xff0c;我们就来聊聊黑盒、白盒测试的相关话题。 1、黑盒测试的方法和小结 最常见黑盒…

C++标准学习--多线程

在以往多线程的实现的时候&#xff0c;都是自己去亲自创建线程&#xff0c;采用特殊flag 及锁控制线程的运转状态。这无可厚非&#xff0c;但又似乎有重复造轮子的嫌疑。最近发现了一个线程池的轮子&#xff0c;很不错&#xff0c;ZZ一下。 C多线程线程池&#xff08;全详解&a…

免费学习鸿蒙(HarmonyOS)开发,一些地址分享

HarmonyOS万物互联&#xff0c;从华为一系列的操作来看已经与iOS、Android形成三足鼎立之势了。 根据《澎湃新闻》的报道&#xff0c;已有23所985高校和46所211高校加入了鸿蒙班的行列&#xff0c;合计达到了69所国内一流高校。通过鸿蒙班的设立&#xff0c;高校可以为学生提供…