tomcat

一、tomcat基础

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

1、简介

tomcat是基于java开发

1)Tomcat服务器是一个免费的开源的Web应用服务器,轻量级应用服务器。

部署jekkies已经用过,jekkies的war包直接放到tomcat的webapp下就可以,springboot项目也是内置了tomcat

2)Tomcat和Nginx区别

Tomcat和Nginx、Apache:都可以作为Web服务器。

web容器是通过计算机网络四层模型提供web服务,在web容器中通过socket方式监听客户端连接。

Tomcat与Nginx:Nginx仅支持静态资源,主要用来做反向代理
Tomcat支持jsp动态资源和静态资源

3)tomcat与apache区别:

apahce处理静态资源效率高,处理动态servlet请求效率低、
Tomcat处理动态servlet请求效率高,处理静态资源效率低

现在的基础架构都是动静分离:配合使用apache/nginx + tomcat

2、安装

tomcat是依赖于jdk,即首先安装jdk。
1)jdk下载安装
https://editor.csdn.net/md/?articleId=125342814
2)tomcat下载安装
下载地址: https://tomcat.apache.org/download-90.cgi
上传至服务器
在这里插入图片描述

解压:
tar -zxvf apache-tomcat-9.0.19.tar.gz -C /usr/local
在这里插入图片描述
修改端口号
在这里插入图片描述
vim server.xml
默认为8080,改为8580
在这里插入图片描述
保存后,进入bin目录,./startup.sh,启动tomcat
ps -ef |grep tomcat
在这里插入图片描述
访问,ip:8580
在这里插入图片描述
查看tomcat版本
./version.sh
在这里插入图片描述

3、架构图(来自百度图片)

在这里插入图片描述
可以参考https://blog.csdn.net/xlgen157387/article/details/79006434
流程:client客户端,CONNNECTOR连接器处理请求,交给Engine,Engine会分发请求给host,host请求会分发请求给Context(代表一个web项目)

还可以分为:

server:顶级组件(最外层),就是运行在jvm里的实例

service、Engine、host、Context容器内组件

结合server.xml

4、目录介绍

在这里插入图片描述

bin、conf、lib、logs、webapps、RELEASE-NOTES、RUNNING.txt、tem、站点配置

1)bin目录(重要)

包含启动、停止服务的脚本以及脚本依赖的文件
在这里插入图片描述
绿色的为可执行文件

①启动tomcat服务:startup.sh

通过jps -l可以看java进程

在这里插入图片描述
这个20567就是tomcat,里面有main方法

在这里插入图片描述

②停止tomca服务:shutdown.sh

也可以直接kill 20567

catalina.sh是一个启动文件,执行startup.sh会调用catalina.sh
在这里插入图片描述

③catalina.sh文件可以配置jvm参数

放在文件第一行

JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log"

相关参数会在catalina.sh这个配置文件里进行。
如要配一个rm的远程连接则加上:

JAVA_OPTS="$JAVA_OPTS-Djava.rmi.server.hostname=XX.XX.XX.XX -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

输入vi startup.sh,会查看到有EXECUTABLE=catalina.sh
在这里插入图片描述

查看版本:./version.sh

日志:

vim catalina.sh
CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
$CATALINA_BASE /usr/local/apache-tomcat-9.0.19

在这里插入图片描述

2)conf目录(重要)

conf目录就是配置文件目录在这里插入图片描述
在这里插入图片描述
比较重要的是server.xml文件
conf的server.xml
server.xml,主配置文件
提取出来结构是如下
在这里插入图片描述

在这里插入图片描述

①结构和架构图是对应的。

最外层server:一个tomcat实例就是一个server

service:将connector关联至engine,可以有多个connector,只能有一个引擎engine

connector连接器:接收用户请求,可以配置多个Connector,默认8080,tomcat本身对外提供服务的默认端口号

和connector平级的是engine,都在service里
engine有host,host下面有context

用户发送请求后连接器去处理请求,把请求交给engine,engine会分发给host,host再转移给context,context代表一个web项目

②重点关注connector 连接器
特点1:接收用户请求
特点2:connector可以配置多个,必须要暴露不同接口。
特点3:默认端口是8080

此处的端口已经改了,默认是8080
在这里插入图片描述
这个8009端口的连接器是和apache做集成时用的
在这里插入图片描述

③连接器和连接池的连接器不能共存

在这里插入图片描述
下面此处还有一个connector,但是他的executor是TomcaThreadpoo,
l这两个名称对应

nameprefix是表示tomcat线程以catalina-exe这种名称开头

在这里插入图片描述

maxThreads="150最大线程池,如果使用的是executor=tomcatThreadPool ,此处最大的线程池是150

minSpareThreads最小空闲线程池 ,默认是4,就就是如果有新的请求,就从空闲线程池进行获取,如果空闲线程不足4
个,tomcat会启动线程,重新构建4个,这样就不需要新的请求去创建线程,如果有空闲线程,直接获取就能用,这样比较快速,性能也会高一些。

在这里插入图片描述

如果使用的是这个connector,他的最大线程池是200

在这里插入图片描述

< connector port =8580>这个模块的下方
还可以配线程池,但是和线程池不能冲突(在service下的< executor="tomcatThreadPool )
< executor="tomcatThreadPool namePrefix=“catlina-exec”
maxThreads=“150” minSpareThreads=“4”/>
tomcat线程池,这里是Executor实现的线程池,maxThreads最大线程池,150(tomcat默认最大线程池是200)minSpareThreads,最小空闲线程池 namePrefix="catlina-exec"表示的是tomcat进程是以这个开头

要用就需要在connector下指定线程池
如< Connector executor=“tomcatThreadPool”
port=“8080” protocol=“HTTP/1.1”
connectiontimeout=“2000”
redirectPort=“8443”/>

Executor实现的线程池
tomcatThreadPool
在这里插入图片描述
maxThreads,最大线程池(tomcat默认最大线程池是200)
minSpareThreads,表示最小空闲连接池
maxSpareThreads,表示最大空闲连接池
acceptCount请求队列,队列满,后续请求被拒绝(linux连接队列中有一个baklog,针对于tomcat中的baklog就是这个参数)

engine:将请求转至对应的虚拟主机host

host:类似nginx的多站点(server ),一个host就是一个站点

context:最内层的容器,类似于nginx中location的概念,代表一个web项目

配置context的目的是为了指定对应webapps的目录,指定额外的属性

其它:valve阀门,是tomcat组件层面的过滤器
说明:和线程池不能冲突
tomcat线程池
Connector executor="tomcatThreadPool
在这里插入图片描述
是通过Executor实现的线程池
在这里插入图片描述

maxThreads,最大线程池,150(tomcat默认最大线程池是200)
minSpareThreads,表示最小空闲连接池
maxSpareThreads,表示最大空闲连接池
acceptCount允许请求排队的队列,如果超过了,请求排队队列
队列满,后续请求被拒绝

minSpareThreads,表示最小空闲连接池

3)lib目录

tomcat运行需要加载的jar包

4)logs目录

tail -f catalina.out

jps -l
主运行文件
在这里插入图片描述

5)webapps目录(重要)

在这里插入图片描述

Web应用程序根目录,部署jekkies已经用过,jekkies的war包直接放到tomcat的webapp下就可以
docs,帮助文档
ROOT,默认网站根目录
直接访问tomcat网页,其实获取的就是index.jsp

在这里插入图片描述
在这里插入图片描述
下面说一下监控,自带status

6)RELEASE-NOTES目录

版本特性

7)RUNNING.txt

帮助文档

8)temp目录

临时文件

9)站点配置

二、监控

除了自带status监控还需要对日志进行监控
Java应用主要看jvm堆,jvm栈,以及jvm容器
而tomcat就是一个容器,而针对于容器主要调优就是配置。

第一个监控:自带status

①主要用于测试监控,生产环境不要用。

tomacat是有管理功能
配置:Tomcat管理功能(对tomcat自身以及部署在上面的应用进行管理)
默认状态是禁用
如果要启用这个功能需要配置管理用户

在这里插入图片描述
监控访问的页面是http://ip端口/mangager/status

在这里插入图片描述

若没有去配置看到的结果就是这样的
此处也会给一些提示,会有不同角色,每个角色都有status page
在配置时随便用一个用户就ok

在这里插入图片描述

②配置

要进行三个配置

第一个配置:conf下tomcat-users.xml

加上角色,同时把用户和密码加在此处
tomcat管理用户用户的配置文件

在这里插入图片描述
在文件的末尾加上,表示角色

<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat666" roles="manager-gui"/>

在这里插入图片描述

第二个配置:/webapps/manager/META-INF/context.xml

allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />改为

allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|\d+\.\d+\.\d+\.\d+"/>

在这里插入图片描述
在这里插入图片描述

第三个配置/webapps/host-manager\META-INF\context.xml
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

改为allow=“127.\d+.\d+.\d+|::1|0:0:0:0:0:0:0:1|\d+.\d+.\d+.\d+”/>
在这里插入图片描述

改完后需要重启服务

页面上访问[http://ip:8080/manager/status]
刚才配置了账号和密码,此处需要用户名和密码登录
tomcat/tomcat666
在这里插入图片描述
此处就是status展示的内容
此处有环境版本的相关信息
也有jvm相关信息

在这里插入图片描述
刚才看server.xml,里面是启动了两个连接器,一个默认是8080(此处端口已经改成8780端口),另一个是8090

在这里插入图片描述

重点是看8780
此处默认最大线程数200,当前线程数10,当前繁忙线程10(如果繁忙和max线程相等,线程都在干活,最大线程数200,可以将最大线程数调大)

在这里插入图片描述
单个请求的最大处理时间
请求处理总时间
请求总数
可以算出处理每个请求的平均时间:处理时间/总的请求数
发生错误的请求数
接收的字节数
发送字节数

在这里插入图片描述
最大
jvm方式还是建议用之前的命令方式。

第二个监控:日志监控

主要是为了拆分时间

①消耗时间(tomcat本身及后续服务消耗的)

若没有链路监控工具,可以在日志记录他的请求响应时间,做日志监控。

②单独的tomcat容器

关于tomcat,如果是单独的omcat容器,比如说应用打了一个war包。把war放在tomcat的webapps目录下,像这种单独的容器,可以在conf/server.xml 中进行配置,如果是用springboot打的jar包(它里面已经内置了tomcat)就去yaml文件进行配置。

pattern中比较重要的参数

在 conf/server.xml 中–log–Value
可以指定日志的pattern:
pattern: ‘%h %l %u %t “%r” %s %b %D %F’
%D请求时间 单位ms
%F响应时间,单位ms

两个是有差异
%D是tomcat接收到请求,到把结果返回,这段时间的耗时,即就是处理请求所有的时间。
%F是tomcat把请求发到下一个服务(比如到数据库里查询数据,从它发请求到mysql到它接收响应这段时间,可以理解为后端的响应时间)

在日志需要看请求和响应时间,就这么配置。
在 conf/server.xml 中–log–Value加上如下:
在这里插入图片描述

< Value classname=“org.apache.catalina.valves.AccessLogValve” directory=“logs”
prefix=“locaL_access_log” suffix=“.txt”
pattern=“%h %l %u %t “%r” %s %b %D %F” />
属性值classname director 日志存放的目录
prefix日志前缀 suffix日志后缀

③springboot内置tomcat容器

比如:yml文件中配置
server下的tomcat
配置了日志格式、前缀、以及放在哪个位置
在这里插入图片描述

请求时间(nginx转发过来的请求,tomcat接收到nginx转发的请求,处理结束,把这个结果完全返回,即就是处理请求的所有的时间)、响应时间(tomcat把请求发到mysql,查数据,mysq处理后把数据返回给tomcat,tomcat本身、后续服务消耗的时间以及网络上消耗的时间)
在这里插入图片描述

2、命令(Java应用)

jps -l
jstat -gcutil pid 1000
jmap -histo pid
show_busy-java-threads.sh
arthas

3、可视化

1)jconsole

tomcat定义了一些MBean,可以对外暴露一些状态信息。
可以通过配置jmx远程监听暴露出来。
远程云服务器,配置jmx远程监听。
配置路径:/usr/local/apache-tomcat-9.0.19/bin/catalina.sh
在这里插入图片描述
加上:
JAVA_OPTS=“$JAVA_OPTS-Djava.rmi.server.hostname=XX.XX.XX.XX -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false”
在这里插入图片描述
重启tomcat
打开jdk bin目录下的jvisualvm.exe,添加远程主机,添加jmx连接,填写对应的端口号即可或者直接在cmd命令框中输入jconsole ip:port

在这里插入图片描述
在这里插入图片描述
cpu占用率是tomcat进程占用的cpu

MBeans–GlobalRequestProcessor有tomcat处理请求的统计信息
在这里插入图片描述
有两个连接器,即在/usr/local/apache-tomcat-9.0.19/conf/server.xml
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

吞吐量、响应时间、错误数
线程池
JVM 内存

2)jvisualvm

线程、jvm
1.进入jdk安装目录的bin目录,双击打开jvisualvm.exe程序
在这里插入图片描述
在这里插入图片描述
点击远程–右键-添加jmx-输入ip:port
在这里插入图片描述

重点看线程
在这里插入图片描述
若tps上不去,并且httpnio的线程达到了设置的最大的线程数且这些线程都是绿色运行状态,就需要把最大线程数调大一些。

三、调优点

第一个调优点:运行模式(重点)

分两种BIO和NIO

①BIO(同步阻塞)

特点就是并发第一,
已经被tomcat8和tomcat做掉。
而tomcat9是NIO

不同的角度
分为:
阻塞,非阻塞、同步、异步
根据应用程序,是否支持运行可以把Io分为阻塞Io,非阻塞io,这里针对的是io调用者。
根据io响应的通知方式,可以分为同步io和异步io,这里针对的是io的执行者。

②NIO(同步非阻塞)

特点是支持高并发

如果对服务器性能要求高,尽量选择NIO

阻塞Io:应用程序在执行io操作后,如果没有获得响应,就会阻塞当前线程,就不能执行其他操作,就会挂起。
非阻塞io:应用程序在执行io操作后,不会阻塞当前线程,可以继续执行其他任务。
同步io:收到io请求后,系统不会立刻响应应用程序,等到处理完后才通过系统调用的方式这是io的结果。
异步io:收到io请求后,系统会先告诉应应用程序,已收到io请求,去异步处理,处理完后,通过事件通知应用程序io结果。

tomcat常见的运行模式是bio,nio
bio:block io,同步阻塞io
特点:并发低(项目对并发不高可以用)、已经被tomcat8.5,9 drop,已经改为nio

nio,同步非阻塞。
特点:支持高并发
两者选择,bio适用于连接数小架构。
nio适用于连接数多的架构。
运行模式的选择,默认就行。
tomcat9默认是nio

若要做日志分析,需要做的配置,配置路径是,:/usr/local/apache-tomcat-9.0.19/bin/catalina.sh
加上:
JAVA_OPTS=“ J A V A O P T S − X X : + U s e r C o n c M a r k S w e e p G C − X X : + P r i n t G C D e t a i l s − X X : + P r i n t G C D a t e S t a m p s − X l o g g c : JAVA_OPTS -XX:+UserConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc: JAVAOPTSXX:+UserConcMarkSweepGCXX:+PrintGCDetailsXX:+PrintGCDateStampsXloggc:CATALINA_HOME/logs/gc.log”

第二个调优点:jvm调优

若cpu高、用户态消耗高,耗时多,gc频繁需要对jvm进行优化,这是jvm优化的前提。

不管什么情况,都应该先优化耗时多的,java应用耗时多到底是代码耗时多还是gc耗时多,都需要去判断。
若cpu高,gc频繁,gc耗时多,考虑gc.
若cpu高,不是gc频繁,gc耗时不多,看代码耗时是否多,可以trace方法,打栈,看一下线程都在干啥,若是等待资源(等待线程池连接、数据库连接,看到这些就去调配置,若不是的话,就根据栈信息进行分析,看到底在做什么。若大量线程都在等待某一个锁,看一下锁被谁持有,在做什么操作,还要看代码加锁粒度,粒度大也会加大阻塞,锁粒度在满足业务情况下,越小越好。

参考jvm思维导图
tomcat的jvm参数

catalina.sh
JAVA_OPTS=“ J A V A O P T S − X X : + U s e C o n c M a r k S w e e p G C − X X : + P r i n t G C D e t a i l s − X X : + P r i n t G C D a t e S t a m p s − X l o g g c : JAVA_OPTS -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc: JAVAOPTSXX:+UseConcMarkSweepGCXX:+PrintGCDetailsXX:+PrintGCDateStampsXloggc:CATALINA_HOME/logs/gc.log”
jstat
可视化
prometheus + grafana

看配置相关
tomcat是一个容器,请求到connector,针对tomcat架构,优化的地方是connector的配置:线程池、最大、最小空闲连接超时时间,内部的组件基本没有可优化。

第三个调优点:线程池(线程池)

官网:https://tomcat.apache.org/tomcat-9.0-doc/config/executor.html

①关键参数:

类:org.apache.catalina.core.StandardThreadExecutor

第一个参数:maxThreads

处理请求的最大线程数,默认200.

根据实际情况进行调整

最大线程数设置多少,结合业务,通过拆解时间发现应用耗时多,就需要考虑两个维度:代码,配置。
优先代码,如果慢,就先trace这个接口调用的方法,看耗时情况,若代码没问题,考虑线程数配置,可以jstack打栈看等待线程池连接、数据库连接,看到这些配置不能支持现在的压力测试,需要调大。
minSpareThreads 最小空闲连接
maxIdleTime最大空闲时间
protected int maxIdleTime = 60000;最大的空闲时间
maxIdleTime,线程最大的空闲时间,并且线程数程空闲时间大于最小空闲线程数,minSpareThreads若配置的10,现在空闲线程数有20个,空闲就可以回收,所以就设置最大空闲时间,超出这个最大空闲时间,多出的10个就回收。

accptCount接受排队的请求(Linux队列的关键的参数配合使用)

protected int maxThreads = 200;

第二个参数: minSpareThreads 最小空闲线程数

最好就是保证一定量的空闲线程,这样有请求来时,有请求来,最小空闲线程数就可以去处理,否则就要去创建线程(需要耗费时间)

protected int minSpareThreads = 25;

第三个参数:maxIdleTime最大空闲时间

最大空闲时间,默认是60s,即1分钟

如果空闲时间超过设置最小空闲线程数的值,多出来的线程就会被回收

线程就会被回收,前提是保证最小空闲线程数(现在的空闲线程数多余最小空闲线程数,空闲时间超过设置的值,有一部分线程被回收,最终会保留最小空闲线程数)
protected int maxIdleTime = 60000;

最大的空闲时间,maxQueueSize,任务队列的最大长度

第四个参数:accptCount接受排队的请求

之前讲linux说的tcp队列相关参数
若tomcat线程达到最大,后面的请求排队,接受排队的请求个数。
accptCount适当调大,对性能有帮助,Tps会上升。

就是看配置线程池够不够,两种方案,
1)status看
2)jvisualvm线程状态

第四个调优点:其他

注释AJP连接器

用于apache和tomcat集成,nginx更主流
这个可以注释掉。
tomcat解析时会启动xml文件,也会创建对象,这个连接器对象也会占用jvm内存。
AJP默认是8009,若没有用到可以注解。

autoDeploy自动部署

改成false,否则会有线程一直做时序和检查。这个线程也会占用服务器资源。

tomcat利用socket接收网络请求
tomcat是servlet容器,也就是说,tomcat内置了servlet容器
servlet
server + applet
applet:客户端应用程序
sevlet:服务端应用程序
sevlet API,是一套规范
Servlet
ServletRequest
ServletResponse
jetty也是Servlet规范实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值