Tomcat
简介
Tomcat是一款我们平时开发过程中最常用到的Servlet容器。本系列博客会记录Tomcat(以Tomcat 7为列)的整体架构、核心组件、IO线程模型、请求在Tomcat内部的流转过程以及一些Tomcat调优的相关知识点。力求能达到以下几个目的:
- 更加熟悉Tomcat的工作机制,工作中遇到Tomcat相关问题能够快速定位,从源头来解决;
- 对于一些高并发场景能够对Tomcat进行调优;
- 通过对Tomcat源码的分析,吸收一些Tomcat的设计的理念,应用到自己的软件开发过程中。
什么是Tomcat
Tomcat是一款Apache下面的开源的Servlet容器,实现了对Servlet和JSP规范的支持。另外 Tomcat 本身内含了一个 HTTP 服务器,所以也可以被当作一个 Web 服务器来使用。但是Tomcat作为一个Web服务器,它对静态资源的处理能力要比Apache或者Nginx这类的Web服务器差很多,所以我们经常将Apache和Tomcat(或者是Nginx和Tomcat)组合使用,Apache来充当Web服务器处理静态资源的请求,Tomcat充当Servlet容器来处理动态请求。
Tomcat的组成
主要有 Container 和 Connector 以及相关组件构成。
如下图
Server:指的就是整个 Tomcat 服 务器,包含多组服务,负责管理和 启动各个 Service,同时监听 8005 端口发过来的 shutdown 命令,用 于关闭整个容器 ;
Service:Tomcat 封装的、对外提 供完整的、基于组件的 web 服务, 包含 Connectors、Container 两个 核心组件,以及多个功能组件,各 个 Service 之间是独立的,但是共享 同一 JVM 的资源 ;
Connector:Tomcat 与外部世界的连接器,监听固定端口接收外部请求,传递给 Container,并 将 Container 处理的结果返回给外部;
Container:Catalina,Servlet 容器,内部有多层容器组成,用于管理 Servlet 生命周期,调用 servlet 相关方法。
Loader:封装了 Java ClassLoader,用于 Container 加载类文件; Realm:Tomcat 中为 web 应用程序提供访问认证和角色管理的机制;
JMX:Java SE 中定义技术规范,是一个为应用程序、设备、系统等植入管理功能的框架,通过 JMX 可以远程监控 Tomcat 的运行状态;
Jasper:Tomcat 的 Jsp 解析引擎,用于将 Jsp 转换成 Java 文件,并编译成 class 文件。 Session:负责管理和创建 session,以及 Session 的持久化(可自定义),支持 session 的集
群。
Pipeline:在容器中充当管道的作用,管道中可以设置各种 valve(阀门),请求和响应在经由管 道中各个阀门处理,提供了一种灵活可配置的处理请求和响应的机制。
Naming:命名服务,JNDI, Java 命名和目录接口,是一组在 Java 应用中访问命名和目录服务的 API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象,目录服务也是一种命名 服务,对象不但有名称,还有属性。Tomcat 中可以使用 JNDI 定义数据源、配置信息,用于开发 与部署的分离。
Container组成
Engine:Servlet 的顶层容器,包含一 个或多个 Host 子容器;
Host:虚拟主机,负责 web 应用的部 署和 Context 的创建;
Context:Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管 理所有的 Web 资源;
Wrapper:最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创 建、执行和销毁。
Tomcat的优缺点
Tomcat开源,免费, 经过长时间的发展(先发优势),它已经广泛的被市场接受和认可,相对 Jetty 和 Undertow来说 Tomcat 还是更加稳定和成熟的,尤其在企业级应用方面,Tomcat 仍然是第一选择。
Tomcat部署
环境说明
主机名 | ip | 职责 |
---|---|---|
localhost | 192.168.58.111 | Tomcat |
环境准备
关闭防火墙
[root@localhost ~]# systemctl disable enable --now firewalld [root@localhost ~]
[root@localhost ~]# setenforce 0
安装依赖包和工具
yum -y install java-17-openjdk* wget vim
下载Apache-tomcat包
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.54/bin/apache-tomcat-9.0.54.tar.gz
解压
[root@localhost ~]# tar xf apache-tomcat-9.0.53.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost ~]# ls
apache-tomcat-9.0.53 bin etc games include lib lib64 libexec sbin share src
[root@localhost ~]# mv apache-tomcat-9.0.53 tomcat
编写一个java页面
cat > index.jsp <<EOF
> <html>
> <head>
> <title>test page</title>
> </head>
> <body>
> <%
> out.println("Hello World");
> %>
> </body>
> </html>
> EOF
[root@localhost ~]# mkdir /usr/local/tomcat/webapps/test
[root@localhost ~]# cp index.jsp /usr/local/tomcat/webapps/test/
启动Tomcat,查看web界面内容
[root@localhost ~]#cd /usr/local/tomcat/bin/
[root@localhost bin]#ls
bootstrap.jar ciphers.sh daemon.sh setclasspath.bat startup.sh //启动脚本 version.bat
catalina.bat commons-daemon.jar digest.bat setclasspath.sh tomcat-juli.jar version.sh
catalina.sh commons-daemon-native.tar.gz digest.sh shutdown.bat tomcat-native.tar.gz
catalina-tasks.xml configtest.bat makebase.bat shutdown.sh //停止脚本 tool-wrapper.bat
ciphers.bat configtest.sh makebase.sh startup.bat tool-wrapper.sh
启动tomcat
[root@localhost bin]# /usr/local/tomcat/bin/startup.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@localhost bin]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 1 [::ffff:127.0.0.1]:8005 *:*
LISTEN 0 100 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
测试访问test java文件
ip+8080端口 访问Tomcat Web管理界面
Tomcat Web界面管理 (配置)
报错(没有用户和登录权限)
修改 tomcat-users.xml 用户管理文件
[root@localhost ~]# cd /usr/local/tomcat/
[root@localhost tomcat]# ls webapps/
docs examples host-manager manager ROOT test
[root@localhost tomcat]# cd conf/
[root@localhost conf]# vim tomcat-users.xml
·······
56 <role rolename="manager-gui"/> ## 添加一个manager用户
57 <user username="tomcat" password="tomcat" roles="manager-gui"/> ##并设置一个密码
58 </tomcat-users>
修改配置文件,将IP加入 \d表示数字至少一个,因为需要转译,所以加\
配置web 访问管理文件
[root@localhost conf]# vim /usr/local/tomcat/webapps/manager/META-INF/context.xml
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
22 allow="192\.168\.58\.\d+|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0 :0:1" />
重启tomcat
先kill tomcat 的进程
[root@localhost ~]# /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
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
再启动
[root@localhost ~]# /usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@localhost ]# ss -anlt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 1 ::ffff:127.0.0.1:8005 :::*
LISTEN 0 100 :::8080 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25
中间有一个登录界面,设置了密码保存,所以没有弹出
用户密码都i是tomcat
同上面一样的 问题
添加一个admin和web 访问地址 用即可
修改 /usr/local/tomcat/conf/tomcat-users.xml 文件
[root@localhost~]# vim /usr/local/tomcat/conf/tomcat-users.xml
<user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<role rolename="admin-gui"/> ##添加此行
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/> # 添加,admin-gui
##修改下面这个路径中的文件,将IP加入,保存退出
[root@localhost ~]# vim /usr/local/tomcat/webapps/host-manager/META-INF/context.xml
·····
sameSiteCookies="strict" />
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="192\.168\.58\.\d+|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
·····
重启tomcat
先kill tomcat 的进程
[root@localhost ~]# /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
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
再启动
[root@localhost ~]# /usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.