文章目录
一、简介
1. 历史
- 1996 年底,SUN 公司发布了 Servlet 第一版规范。
- 1997 年 SUN 公司软件架构师 James Duncan Davidson,开发了 Servlet 的参考实现项目 Java Web Server。
- 1999 将项目贡献给了 ASF,和 ASF 现有的 JServ 项目合并发布初始版本 Tomcat 3.0,实现了 Servlet 2.2 和 JSP 1.1 规范。
- Tomcat 仅仅实现了 Java EE 规范中与 Servlet、JSP 相关的类库,是 JavaEE 不完整实现。
- 2001 年 Tomcat 4.x 发布时,内建了 Catalina(Servlet容器)和 Jasper(JSP engine)等。
- 2005 年成为 Apache 顶级项目。
2. 应用场景
Tomcat 是 Apache 的扩展,是 Apache 的一个子项目,它具备 Web 服务器的所有功能,不仅可以监听接受请求并响应静态资源,而且可以在后端运行特定规范的 Java 代码 Servlet,同时将执行的结果以 HTML 代码的形式返回客户端。
Tomcat 虽然和 Apache 或者 Nginx 这些 Web 服务器一样,具有处理 HTML 页面的功能,然而由于其处理静态 HTML 的能力远不及 Apache 或者 Nginx,所以 Tomcat 通常是作为一个 Servlet 和 JSP 容器,单独运行在后端。
3. 组件
Tomcat 由一系列的组件构成,其中核心的组件有三个
名称
功能
Web 容器
完成 Web 服务器的功能( 如 HTTP/HTTPS 请求的接受和响应 )
Servlet 容器
由名称为 catalina 的脚本来处理 Servlet 代码( 如从数据库中拿取数据给与前端 )
JSP 容器
用于将 JSP 动态网页翻译成 Servlet 代码( index.html index.php index.jsp )
二、Tomcat 详述
1. Tomcat 核心组件详解
1.1 Web 容器
负责 WEB 服务的 TCP/IP、HTTP/HTTPS 等协议响应、处理 (nginx 处理静态页面的应用交互)
1.2 JSP 容器(JAVA Scripts page)
- 一种动态网页开发技术
- 它使用 JSP 标签在 HTML 网页中插入 Java 代码,通常以 <%开头,以%>结束
- JSP 是一种 Java servlet,主要用于实现 Java web 应用程序的用户界面部分
- JSP 通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页
1.3 Servlet 容器
- 由名称为 catalina.sh 的脚本来处理 Servlet 代码(Servlet 代码是由 Java 编写的)
- Servlet 容器调用 API 接口,找到对接的项目,对接的项目从 mysql 数据库中获得相应信息,比如:数据库交互、加密、支付宝、人脸识别等,处理完后会将这些数据返回给 jsp,通过 jsp 中的 index.jsp 展示出来,再把相应信息返回给客户
2. Tomcat 请求处理过程
① 用户点击网页内容,请求被发送到本机端口 8080,Service 作为一个进程支持 Tomcat,Connector 作为一个连接器(连接 nginx 或者外部请求),等着去监听 HTTP1.1 版本中的 8080 端口(Coyote:可以看做运行 Connector 连接器运行的环境);
② 交给后端 container 容器中的 Engine(支持容器正常运行的引擎);
③ 在引擎所支持的 container 容器内会有一个项目 host(比如支付宝、淘宝等),进行交互,借助于 context 做连接的服务,连接的是 java 的前端和后端;
④ 交给 servlet 处理 java 后端数据与数据库交互;
⑤ servlet 处理完会返回给 context(连接器);
⑥ context 返回给 engine 引擎;
⑦ engine 引擎返回给端口,最终通过映射端口的方式将页面展现给客户。
三、Tomcat 安装
1. YUM 安装
centos7 中自带的 yum 源中是 Tomcat 7.0 版本。安装完通过浏览器可以观察一下首页。
yum -y install tomcat tomcat-admin-webapps tomcat-webapps
systemctl start tomcat.service && systemctl enable tomcat.service
ss -anlt
#依赖安装 tomcat-jsp、tomcat-servlet
2. 预下载安装包安装
2.1 安装 JDK 环境
[root@c7-1 ~]#systemctl stop firewalld && systemctl disable firewalld
[root@c7-1 ~]#setenforce 0
[root@c7-1 ~]#ls
apache-tomcat-9.0.16.tar.gz jdk-8u201-linux-x64.rpm
[root@c7-1 ~]#rpm -i jdk-8u201-linux-x64.rpm
警告:jdk-8u201-linux-x64.rpm: 头V3 RSA/SHA256 Signature, 密钥 ID ec551f03: NOKEY
Unpacking JAR files...
tools.jar...
plugin.jar...
javaws.jar...
deploy.jar...
rt.jar...
jsse.jar...
charsets.jar...
localedata.jar...
[root@c7-1 ~]#cat >> /etc/profile.d/java.sh <<EOF
> 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:$PATH
> EOF
[root@c7-1 ~]#source /etc/profile.d/java.sh
[root@c7-1 ~]#java -version
openjdk version "1.8.0_222-ea"
OpenJDK Runtime Environment (build 1.8.0_222-ea-b03)
OpenJDK 64-Bit Server VM (build 25.222-b03, mixed mode)
CLASSPATH:编译、运行 Java 程序时,JRE 会去该变量指定的路径中搜索所需的类( .class )文件
dt.jar:关于运行环境的类库,主要是 swing 的包
tools.jar:主要是一些 jdk 工具的类库,包括 javac,java,javap,javadoc 等
JDK:java development kit( Java 开发工具)
JRE:java runtime environment( Java 运行时环境)
JVM:java virtuak machine( Java 虚拟机),使 Java 程序可以在多种平台上运行 .class 文件
编写一个简单的 JAVA 文件验证下
[root@c7-1 ~]#cat > test.java <<EOF
> public class test {
> public static void main(String[] args){
> System.out.println("Hello world!");
> }
> }
> EOF
[root@c7-1 ~]#javac test.java
[root@c7-1 ~]#ls
apache-tomcat-9.0.16.tar.gz jdk-8u201-linux-x64.rpm test.class test.java
[root@c7-1 ~]#java test
Hello world!
2.2 安装 Tomcat
[root@c7-1 ~]#ls
apache-tomcat-9.0.16.tar.gz jdk-8u201-linux-x64.rpm test.class test.java
[root@c7-1 ~]#tar xf apache-tomcat-9.0.16.tar.gz
[root@c7-1 ~]#mv apache-tomcat-9.0.16 /usr/local/tomcat
[root@c7-1 ~]#/usr/local/tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@c7-1 ~]#netstat -antp | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 61653/java
[root@c7-1 ~]#ln -s /usr/local/tomcat/bin/startup.sh /usr/local/bin/
[root@c7-1 ~]#ln -s /usr/local/tomcat/bin/shutdown.sh /usr/local/bin/
#优化了启动方式后就可以在任意目录开启和关闭 tomcat 了
浏览器访问 http://<你的IP>:8080 查看 Tomcat 首页
tomcat 主要目录说明
[root@c7-1 ~]#ls /usr/local/tomcat/
bin BUILDING.txt conf CONTRIBUTING.md lib LICENSE logs NOTICE README.md RELEASE-NOTES RUNNING.txt temp webapps work
目录
说明
bin
存放 Windows 或 Linux 平台上启动和关闭 Tomcat 的脚本文件
conf
存放 Tomcat 服务器的各种全局配置文件,其中最重要的是的是 server.xml 和 web.xml
lib
存放 Tomcat 运行需要的库文件(JARS),一般不作任何改动,除非连接第三方服务,比如 redis,那就需要添加相对应的 jar 包
logs
存放 Tomcat 执行时的 LOG 文件(日志)
temp
存放 Tomcat 运行时产生的文件
webapps
Tomcat 的主要 Web 发布目录(包括应用程序示例),是存放项目资源的目录
work
Tomcat 工作目录,存放 jsp 编译后产生的 class 文件,一般清除 Tomcat 缓存的时候会使用到
优化 Tomcat 启动速度
#生产环境中第一次启动 Tomcat 可能会发现 Tomcat 启动很慢,默认情况下可能需要几十秒,此时可以修改 JDK 参数进行优化
vim /usr/java/jdk1.8.0_201-amd64/jre/lib/security/java.security
------修改117行-----
securerandom.source=file:/dev/urandom
#重启生效
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
# /dev/random 和 /dev/urandom 都是伪终端,但是 /dev/urandom 提供的数据流更快
# JRE 默认使用 /dev/random 作为随机数来源,当熵池大小不够的时候,random 会很慢,造成随机数生成调用阻塞
Tomcat 主配置文件 /usr/local/tomcat/conf/server.xml
#匹配搜索 8080
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" #毫秒
redirectPort="8443" /> # SSL 重定向/映射 443端口(https)
四、Tomcat 虚拟主机
很多时候公司会有多个项目需要运行,那么肯定不可能是一台服务器上运行多个 Tomcat 服务,这样会消耗太多的系统资源。此时就需要使用到 Tomcat 虚拟主机。
例如:现在新增两个域名 www.dog.com 和 www.cat.com,希望通过这两个域名访问到不同的项目内容。
添加主机域名映射
[root@c7-1 ~]#echo "192.168.10.20 www.dog.com www.cat.com" >> /etc/hosts
创建目录及文件
[root@c7-1 ~]#mkdir /usr/local/tomcat/webapps/dog
[root@c7-1 ~]#mkdir /usr/local/tomcat/webapps/cat
//在对应目录下创建默认首页文件,用以测试
[root@c7-1 ~]#echo "hello dog~" > /usr/local/tomcat/webapps/dog/index.jsp
[root@c7-1 ~]#echo "hello cat~" > /usr/local/tomcat/webapps/cat/index.jsp
修改 Tomcat 主配置文件
[root@c7-1 ~]#vim /usr/local/tomcat/conf/server.xml
//在165行插入以下内容
<Host name="www.dog.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/dog" path="" reloadable="true" />
</Host>
<Host name="www.cat.com" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/webapps/cat" path="" reloadable="true" />
</Host>
字段说明
字段
说明
Host name
主机名
appBase
Tomcat 程序工作目录,相对路径为 webapps,绝对路径为 /usr/local/tomcat/webapps
unpackWARs
是否解压 war 包
autoDeploy
指示 Tomcat 运行时,如有新的 WEB 应用是否允许自动部署
xmlValidation
是否验证 xml 文件执行有效性检验的标志
xmlNamespaceAware
是否启用 xml 命名空间,设置该值与 xmlValidation 为 true,表示对 web.xml 文件执行有效性检验
appBase
WEB 应用的目录
path
设置访问的 URI 为 WEB 应用的根目录
reloadable
是否在程序有改动时重新载入
重启 Tomcat
[root@c7-1 ~]#/usr/local/tomcat/bin/shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@c7-1 ~]#/usr/local/tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.8.0_201-amd64
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@c7-1 ~]#netstat -antp | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 67699/java
tcp6 0 0 ::1:38414 ::1:8080 TIME_WAIT -
PS:如果在脚本中重启 Tomcat 最好中间睡眠几秒
/usr/local/tomcat/bin/shutdown.sh
sleep 5 - 10
/usr/local/tomcat/bin/startup.sh
浏览器分别访问 http://www.dog.com:8080 http://www.cat.com:8080
五、Tomcat 优化
- Tomcat 默认安装下的缺省配置并不适合生产环境,它可能会频繁出现假死现象需要重启,只有通过不断压测优化才能让它最高效率稳定的运行
- 优化主要包括三方面:操作系统优化(内核参数优化)、Tomcat 配置文件参数优化、Java 虚拟机(JVM)调优
常用的优化相关参数如下
参数
说明
maxThreads
Tomcat 使用线程来处理接收的每个请求,这个值表示 Tomcat 可创建的最大的线程数,默认值是 200
minSpareThreads
最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 10
maxSpareThreads
最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的 socket 线程。默认值是 -1(无限制)。一般不需要指定
URIEncoding
指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 Web 服务器软件配置方便,需要分别指定
connnectionTimeout
网络连接超时,单位亳秒,设置为 0 表示永不超时,这样设置有隐患的。通常默认 20000 亳秒就可以
enableLookups
是否反查域名,以返回远程主机的主机名,取值为 true 或 false ,如果设置为 false, 则直接返回 IP 地址。为了提高处理能力,应设置为 false
disableUploadTimeout
上传时是否使用超时机制,应设置为 true
connectionUploadTimeout
上传超时时间,毕竟文件上传可能需要消耗更多的时间,这个根据你自己的业务需要自己调,以使 Servlet 有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效
acceptCount
指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为 100 个
compression
是否对响应的数据进行 GZIP 压缩,off 表示禁止压缩、on 表示允许压缩、force 表示所有情况下都进行压缩,默认值为 off,压缩数据后可以有效的减少页面的大小,一般可以减小 1/3 左右,节省带宽
compressionMinSize
表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是 2048
compressableMimeType
压缩类型,指定对哪些类型的文件进行数据压缩
noCompressionUserAgents=“gozilla, traviata”
对于以下的浏览器,不启用压缩
优化实例:
vim /usr/local/tomcat/conf/server.xml
#------71行插入------
minSpareThreads="50"
#最小空闲线程数为 50
enableLookups="false"
#不开启反查域名
disableUploadTimeout="true"
#上传时使用超时机制
acceptCount="300"
#线程数都被占用时,可传入最大连接请求队列为 300
maxThreads="500"
#可创建的最大线程数为 500
processorCache="500"
#控制 Tomcat 内部 RequestProcessor 的缓存池大小,若超过 500,则会创建新的 RequestProcessor 实例
URIEncoding="UTF-8"
#字符集为 UTF-8
compression="on"
#开启对响应的数据进行 GZIP 压缩
compressionMinSize="2048"
#压缩响应最小值,开启则默认 2048,只有大于该值时才会对报文进行压缩
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>
#压缩可支持类型
重启 Tomcat 生效
/usr/local/tomcat/bin/shutdown.sh
sleep 5 - 10
/usr/local/tomcat/bin/startup.sh