目录
一、Tomcat介绍
二、Tomcat核心组件
1、web容器:完成web服务器的功能,web应用
2、servlet容器:名字:catalina,处理servlet代码
servlet的功能
3、jsp:jsp动态页面翻译成servlet代码,用标准格式,展示Jsp的静态页面
拓展:
三、功能组件
四、Tomcat服务部署
编辑
Tomcat启动配置优化:
Tomcat优化:
内核优化:
Tomcat配置JVM参数优化:
一、Tomcat介绍
Tomcat 是一个开放源代码的web应用服务器,基于java代码开发的。
tomcat 就是处理动态请求和基于java代码的页面开发
可以在html当中写入java代码,tomcat可以解析html页面当中的java代码,执行动态请求、动态页面。
机制有问题:不对tomcat进行优化,会出现在:假死、停机。小集群,小服务,小应用使用于tomcat,大并发的场景不适合。
1、免费
2、开源,可以二次封装
3、可配置性强,可以根据需要进行自定义配置,包括端口号,虚拟主机,等等。
4、安全性:tomcat自带安全机制,可以配置用户认证、授权、加密传输。
5、部署应用非常快捷:tomcat会自动部署,自动运行。
webapps。
二、Tomcat核心组件
1、web容器:完成web服务器的功能,web应用
web----->http(s)-------访问页面------>文件index.jsp
web容器中,封装了一组文件,在这一组文件中,进行集中化管理。
管理的就是web动态页面
2、servlet容器:名字:catalina,处理servlet代码
就是处理web请求(http),以及生成动态内容的java类
作用就是处理http请求
servlet的功能
1、处理http请求
2、生成动态内容,为了和数据交互---->用户发起的,jsp当中的。
3、会话管理,跟踪用户在不同请求之间的状态,通过管理,可以在用户访问不同页面时保持用户的状态(就是登录b站后,就会一直保持登录状态,没有退出就会一直保持登录状态)。
session
4、与数据库交互,servlet可以连接到数据库,执行查询和更新操作。这就是servlet能够生成动态内容的原因(可以从数据库中获得最新生成的数据发送给用户)
3、jsp:jsp动态页面翻译成servlet代码,用标准格式,展示Jsp的静态页面
全称:java server pages。
是动态页面的开发技术,使用jsp标签(index.jsp),支持在html页面中插入java代码。
jsp容器----->将html页面当中的java代码翻译----->执行----->展示结果
通常以 <% 为开头,以 %> 为结尾。
大致的工作流程:
(1)用户发送http请求
(2)servlet处理请求
(3)到web容器中去找请求的内容
(4)jsp容器,翻译.jsp文件中的代码,静态页面展示给用户
(5)发回给servlet
(6)最后到用户
拓展:
面向对象:是一种编程的范式或者思想, 把客观存在的实体和他们之间的关系,映射到计算机程序当中。
计算机程序会被组织成一组相互作用的对象,每一个对象都有数据(属性)和行为(方法)
类和对象:
类:定义一组属性和方法。是用来创建对象(实例)的
封装:对象的属性和方法捆绑在一块,提供一个接口,可以让其他对象使用
继承:一个类,可以继承另一个类,父类和子类,子类可以重用父类的代码,而且还在不修改的情况下,进行扩展。
多态:不同类的对象对相同的消息,可以做出不同的响应。
三、功能组件
Server:是最顶级的组件,代表Tomcat的运行实例,在一个JVM中只包含一个,在Server的整个生命周期中,不同阶段会有不同
Service:是服务的抽象,它代表请求从接收到处理的所有组件的集合。设计上Server可以包含多个Service组件,每个Service组件都包含若干用于接收客户端消息的Connector组件和用于处理请求的Engine组件。
connector:负责对外接收和响应请求,是tomcat与外界的交通枢纽。监听端口,也可以接收外界请求,交给container处理。
container:负责对内处理业务逻辑。
Engine:引擎,管理虚拟机 (service,一个service里面可以包含多个虚拟主机。),可以管理多个虚拟主机,但是,每个service只能有一个Engine
Host:代表一个虚拟机,也可以叫站点,
Context:web应用,可以包含多个servlet
wrapper:封装器,最底层,每一个wrapper都封装一个servlet。负责对象实例的创建、执行以及销毁。
Engine、Host、Context、wrapper这四个组件是父子关系,工作方式也是从上到下的。
工作流程:
1、输入网址,请求发送,请求发送到8080端口,被监听的connector获得;
2、connector会把请求转发到container功能组件中的Engine(管理虚拟主机,你要访问哪一个虚拟主机)组件中处理,并等待来自Engine的回应并返回给客户。Engine从Connector那里获得该对应的请求localhost:8080/test/index.jsp,并进行匹配该对应的虚拟主机Host(主机站点包含要请求页面的位置,webapps)
3、匹配到名为localhost的Host(主机站点包含要请求页面的位置,webapps)后。
4.localhost Host获得请求/test/index.jsp,并匹配其所拥有的context,就是index.jsp里面的内容------->wrapper(servlet,响应解析处理这些请求)-----jsp翻译官-------页面展示
5、匹配到路径为/test的Context,并获得请求/test/index.jsp,并在其mapping table中寻找对应的Servlet,Context匹配到URL PATTERN后缀名为.jsp的Servlet,对应于JSPServlet类。
6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法。
7、Context将执行完毕之后的HttpServletResponse对象返回给Host
8、Host将HttpServletResponse对象返回给Engine
9、Engine将HttpServletResponse对象返回给Connector
10、Connector将HttpServletResponse对象返回给客户浏览器
总结:用户发起请求,到连接器,通过8080转发到container,再到引擎engine,再到Host,再到context,再到servlet,也就是wrapper,把.jsp文件的内容解析出来,再反过来,一层一层发回。
四、Tomcat服务部署
在部署 Tomcat 之前必须安装好 jdk,因为 jdk 是 Tomcat 运行的必要环境。
1.关闭防火墙,将安装 Tomcat 所需软件包传到/opt目录下
jdk-8u201-linux-x64.rpm
apache-tomcat-9.0.16.tar.gzsystemctl stop firewalld
systemctl disable firewalld
setenforce 02.安装JDK
cd /opt
rpm -ivh jdk-8u201-linux-x64.rpm
java -version3.设置JDK环境变量
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$PATHexport JAVA_HOME=/usr/java/jdk1.8.0_201-amd64:
这个命令设置了一个名为JAVA_HOME的环境变量,它指向Java JDK的安装路径。
这对于告诉系统和其他应用程序Java的安装位置非常重要。你需要将路径替换为你实际安装Java的路径。export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:
这个命令设置了一个名为CLASSPATH的环境变量,它用于指定Java类的搜索路径。
在这个命令中,.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar 表示当前目录(.)
以及Java工具库(tools.jar)和Java远程调试库(dt.jar)的路径。这些库通常包含一些Java开发所需的类。export PATH=$JAVA_HOME/bin:$PATH:
这个命令将Java可执行文件的路径添加到系统的PATH环境变量中。
这使得你可以在终端中直接运行Java工具,而不需要输入完整的路径。
这将Java的bin目录添加到了PATH中,使得java、javac等命令可以直接运行。source /etc/profile.d/java.sh
java -version----------------------------------------------------------------------------------------------------------
CLASSPATH:编译、运行Java程序时,JRE会去该变量指定的路径中搜索所需的类(.class)文件。
dt.jar:是关于运行环境的类库,主要是可视化的 swing 的包。
tools.jar:主要是一些jdk工具的类库,包括javac、java、javap(jdk自带的一个反编译工具)、javadoc等。
JDK (Java Development Kit):JDK是Java开发工具包,它是用于开发Java应用程序的软件包。
JDK包括了编译器(javac)、调试器、各种工具、Java标准类库(Java API)、以及Java文档等。
JDK是开发者用来创建、编译和运行Java应用程序的重要组件。JRE (Java Runtime Environment):JRE是Java运行时环境,它是用于执行Java应用程序的部分。
JRE包括了Java虚拟机(JVM)以及Java类库(Java API),这使得用户能够在计算机上运行已编译的Java程序,
而不需要进行开发。JRE是终端用户需要安装的部分,以便能够运行Java应用程序。JVM (Java Virtual Machine):JVM是Java虚拟机,它是Java应用程序在计算机上运行的核心组件。
JVM负责将编译后的Java字节码(.class文件)解释或编译成本地机器码,以便计算机能够执行它。
JVM提供了内存管理、垃圾回收、线程管理等功能,以确保Java程序在不同平台上具有相似的行为。
----------------------------------------------------------------------------------------------------------首先使用文本工具编写java源代码,比如 Hello.java ;
在命令行中,输入命令:javac Hello.java,对源代码进行编译,生成 class 字节码文件;
编译完成后,如果没有报错信息,输入命令:java Hello,运行 class 字节码文件,由 JVM 对字节码进行解释和运行,
打印 “Hello World”。vim Hello.javapublic class Hello { public static void main(String[] args){System.out.println("Hello world!");}
}javac Hello.java
java Hellopublic: 这是一个访问修饰符,表示类是公共的,可以从其他地方访问。
class: 关键字用于定义一个类。
Hello: 这是类的名称,这里是一个叫做 "Hello" 的类。public static void main(String[] args){
public: 访问修饰符,表示这个方法是公共的,可以从其他地方访问。
static: 静态修饰符,表示这个方法属于类而不是实例,可以通过类名直接调用。
void: 这是方法的返回类型,void 表示方法没有返回值。
main: 这是方法的名称,是程序的入口点,当程序运行时会从这里开始执行。
(String[] args): 这是方法的参数列表,args 是一个字符串数组,可以在命令行传递参数给程序。System.out.println("Hello world!");
System.out: System 是一个类,out 是这个类的一个静态成员,它代表标准输出流。
println: 这是输出方法的名称,它会在控制台输出一行内容。
"Hello world!": 这是要输出的内容,是一个字符串。4.安装启动Tomcat
cd /opt
tar zxvf apache-tomcat-9.0.16.tar.gz
mv apache-tomcat-9.0.16 /usr/local/tomcat
##启动tomcat ##
#后台启动
/usr/local/tomcat/bin/startup.sh
或
/usr/local/tomcat/bin/catalina.sh start#前台启动
/usr/local/tomcat/bin/catalina.sh run netstat -natp | grep 8080浏览器访问Tomcat的默认主页 http://192.168.233.21:80805.优化tomcat启动速度
第一次启动tomcat可能会发现 Tomcat 启动很慢,默认情况下可能会需要几十秒,可以修改jdk参数进行改。
vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
--117行--修改
securerandom.source=file:/dev/urandom
----------------------------------------------------------------------------------------------------------
/dev/urandom是/dev/random的非阻塞版本,/dev/random的 random pool 依赖于系统中断,因此在系统的中断数不足时,
/dev/random 设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用,
/dev/random设备可以保证数据的随机性。 /dev/urandom不依赖系统的中断,也就不会造成进程忙等待,
但是数据的随机性也不高,所以该随机数的安全性理论上不高。如果应用对安全性要求很高,那么应该使用/dev/random。
----------------------------------------------------------------------------------------------------------/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh ll /usr/local/tomcat/
------主要目录说明----------------------------------------------------------------------------------------------
●bin:存放启动和关闭Tomcat的脚本文件,比较常用的是 catalina.sh、startup.sh、shutdown.sh三个文件
●conf:存放Tomcat 服务器的各种配置文件,比较常用的是 server.xml、context.xml、tomcat-users.xml、web.xml 四个文件。
① server.xml: Tomcat的主配置文件,包含Service,Connector,Engine,Realm,Valve,Hosts主组件的相关配置信息;
② context.xml:所有host的默认配置信息;
③ tomcat-user.xml:Realm认证时用到的相关角色、用户和密码等信息,Tomcat自带的manager默认情况下会用到此文件,在Tomcat中添加/删除用户,为用户指|定角色等将通过编辑此文件实现;
④ web.xml:遵循Servlet规范标准的配置文件,用于配置servlet,并为所有的web应用程序提供包括MIME映射等默认配置信息;
●lib:存放Tomcat运行需要的库文件的jar 包,一般不作任何改动,除非连接第三方服务,比如 redis,那就需要添加相对应的jar 包
●logs:存放 Tomcat 执行时的日志
●temp:存放 Tomcat 运行时产生的文件
●webapps:存放 Tomcat 默认的 Web 应用部署目录
●work:Tomcat工作日录,存放jsp编译后产生的class文件,一般清除Tomcat缓存的时候会使用到
●src:存放Tomcat 的源代码
●doc:存放Tomcat文档
----------------------------------------------------------------------------------------------------------
查看manager文件:
cd /usr/local/tomcat/webapps/manager/META-INF
vim context.xml<Context antiResourceLocking="false" privileged="true" ><Valve className="org.apache.catalina.valves.RemoteAddrValve"allow=".*" /> #允许所有主机访问。在conf,tomcat-users.xml中,添加账户密码
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>
Tomcat虚拟主机配置:
很多时候公司会有多个项目需要运行,一般不会是在一台服务器上运行多个 Tomcat 服务,这样会消耗太多的系统资源。此时, 就需要使用到 Tomcat 虚拟主机。
例如现在新增两个域名 www.kgc.com 和 www.benet.com, 希望通过这两个域名访问到不同的项目内容。1.创建 kgc 和 benet 项目目录和文件
mkdir /usr/local/tomcat/webapps/kgc
mkdir /usr/local/tomcat/webapps/benet
echo "This is kgc page\!" > /usr/local/tomcat/webapps/kgc/index.jsp
echo "This is benet page\!" > /usr/local/tomcat/webapps/benet/index.jsp2.修改 Tomcat 主配置文件 server.xml
vim /usr/local/tomcat/conf/server.xml
--165行前--插入
<Host name="www.kgc.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"><Context docBase="/usr/local/tomcat/webapps/kgc" path="" reloadable="true" />
</Host> <Host name="www.benet.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"><Context docBase="/usr/local/tomcat/webapps/benet" path="" reloadable="true" />
</Host>----------------------------------------------------------------------------------------------------------
Host name:主机名
appBase:Tomcat程序工作目录,即存放web应用程序的目录;相对路径为webapps,绝对路径为 /usr/local/tomcat/webapps
unpackWARs:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true
autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true
xmlValidation:是否验证xml文件执行有效性检验的标志
xmlNamespaceAware:是否启用xml命名空间,设置该值与xmlValidation为true,表示对web.xml文件执行有效性检验docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;
path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径 / ;
reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false
----------------------------------------------------------------------------------------------------------/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh3.客户端浏览器访问验证
echo "192.168.233.71 www.kgc.com www.benet.com" >> /etc/hosts浏览器访问 http://www.kgc.com:8080/ 页面显示This is kgc page\!
浏览器访问 http://www.benet.com:8080/ 页面显示This is benet page\!----------------------------------------------------------------------------------------------------------
HTTP 请求过程:
(1)Connector 连接器监听的端口是 8080。由于请求的端口和监听的端口一致,连接器接受了该请求。
(2)因为引擎的默认虚拟主机是 www.kgc.com,并且虚拟主机的目录是webapps。
所以请求找到了 tomcat/webapps 目录。
(3)访问的路径为根路径,URI 为空,即空是 Web 程序的应用名,也就是 context。
此时请求找到 /usr/local/tomcat/webapps/kgc 目录,解析 index.jsp 并返回。
----------------------------------------------------------------------------------------------------------
Tomcat优化
Tomcat 配置文件参数优化:
vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
--71行--插入
minSpareThreads="50"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="300"
maxThreads="500"
processorCache="500"
URIEncoding="UTF-8"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>
Tomcat的Connector的配置信息:
minSpareThreads: 空闲线程的最小数量,不运行线程时,默认都会有此值设置的线程数。用于处理请求。开启tomcat时,会有多少线程,默认是10。
enableLookups: 是否启用DNS反向解析。当设置为false时,请求将不会被解析为主机名。
disableUploadTimeout: 是否禁用上传超时,即设置连接不会在上传期间超时。
acceptCount: 当所有线程都在忙碌时,可以排队等待处理的请求数量。
maxThreads: Tomcat可以创建的最大线程数。
processorCache: 连接器可以缓存的最大处理器数。
URIEncoding: URI的字符编码。
compression: 是否启用响应内容压缩。
compressionMinSize: 响应内容压缩的最小大小。超过此值才可以进行压缩。
compressableMimeType: 可以被压缩的MIME类型列表。
浏览器和其他互联网应用程序之间处理文件的协议和需要处理的Mime文档的性质和格式。
文本:text/html,text/plain
图像:image/jpg image/gif
音频:audio/wav aduio/mp3
视频:video/mp4 video/avi
应用程序:application/pdf application/json.
Tomcat启动配置优化:
启动速度优化:
第一次启动tomcat会发现启动速度很慢,10几秒-1分钟
jdk的参数:vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
117行修改:
securerandom.source=file:/dev/urandom
Tomcat内核优化:
永久配置:注意:设置保存后,需要重新ssh连接才会看到配置更改的变化
vim /etc/security/limits.conf
# 65535 为Linux系统最大打开文件数
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535: 最大进程数软限制为 65535,即可以使用 ulimit -u 命令查看和修改的值。
* hard nproc 65535: 最大进程数硬限制为 65535,即最大可分配的进程数。
* soft nofile 65535:最大打开文件数软限制为 65535,即可以使用 ulimit -n 命令查看和修改的值。
* hard nofile 65535:最大打开文件数硬限制为 65535,即最大可分配的文件数。
这里使用的通配符 * 表示对所有用户生效。
Tomcat配置JVM参数优化:
JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -Xmn768m -XX:ParallelGCThreads=2 -xx:PermSize=1024m -XX:MaxPermSize=1024m -Djava.awt.headless=true -XX:+DisableExplicitGC"
-server:第一个参数,指定内存池,一定要放在第一个
-Xms2048m:初始java堆的大小,也就是分配JVM的最小内存。看cpu的性能高,这个值可以设置高一点。
-Xmx2048m:JAVA堆最大能多大,JVM的最大内存,和硬件内存挂钩。根据官方文档起始值和最大值要保持一致。Xms和Xmx设为一样的,内存可以设为物理内存的一半
-Xmn768m:新生代的内存大小,官方推荐为了整个堆大小的3/8(八分之三)
-XX:ParallalGCThreads=2:配置并行收集器的线程数,同时可以有多少个线程进行垃圾回收
-xx:PermSize:设置持久内存的大小,默认设置是物理内存的1/4(四分之一)
-xx:MaxPermSize=1024m:最大的非堆内存的大小,默认也是物理内存的1/4
-xx:PermSize=1024m -XX:MaxPermSize=1024m
非堆内存是不会被垃圾回收机制处理的,-XX:PermSize持久代内存与最大非堆内存不能超出操作系统可用的内存。设置成一样大,可用减轻伸缩堆大小的压力。
-Djava.awt.headless=true:避免在Linux环境下,web不能正常打开以正常显示图片。
-XX:+DisableExplicitGC":避免JVM空间大起大落,影响系统的响应时间。大起大落会导致响应速度会很慢。
-Xss: 设置线程栈的大小。例如:-Xss256k表示设置线程栈的大小为256KB。
JVM优化:
vim /usr/local/tomcat/bin/catalina.sh#在119行中插入以下内容
JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -Xmn768m -XX:ParallelGCThreads=2 -xx:PermSize=1024m -XX:MaxPermSize=1024m -Djava.awt.headless=true -XX:+DisableExplicitGC"./shutdown.sh./startup.sh
JVM:就是java的虚拟机,是java应用程序再计算机上运行的核心组件,jvm负责将编译后的java字节码(.class文件)解释或则和编译成本地的机器码,计算机能够执行它。JVM还提供了内存管理,垃圾回收,线程管理。确保java的程序在不同平台可以有一致性的功能。
堆就是用来工作的,非堆就是存储缓存的(存储垃圾的) 内存不够,会炸。所以要优化
catalina.sh 就是servlet代码,以及容器的配置。
PS Eden Space:堆内存,存储新创建的对象
PS Old Gen:堆内存,存储长时间存活的对象
PS Survivor Space:堆内存,存储创建之后生命周期较短的对象
Code Cache:非堆内存,存储已经编译的代码
Compressed Class Space:非堆内存,存储已经压缩的类
Metaspace:非堆内存,存储类的元数据
堆区当中会进一步细分:新生代 中生代 老年代
每一个新创建的对象占用的空间,就是新生代
java垃圾回收机制会对堆区进行资源回收。资源回收之后,新生代中没有被回收的资源,就是中生代。
中生代没有被回收,就是老年代。
JVM大小:新生代+中生代+老年代+永久代
"ajp-nio-8009":
ajp-nio:连接器的类型 ajp:使用ajp协议。nio进行异步非阻塞。
8009:连接器正在监听的端口号。是connector中的一种
ajp:将tomcat服务器与前端web服务器进行连接。提供负载均衡和高效的请求转发,
tomcat8009是用来和nginx通信的
“http-nio-8080”
处理http请求,和客户端通信的端口。