整体介绍
Tomcat服务器是一个免费开放源代码的Web服务器,轻量级应用服务器。为众多大规模任务关键性网络提供支持,适用于各种行业和组织。
本文中将通过以下内容,从各个方面去对Tomcat进行了解:
- Tomcat 概念与运行原理。
- Tomcat 环境搭建:Windows和Linux环境下搭建Tomcat。
- Tomcat 配置详情:常用配置项修改、web管理界面、单点登录配置、多域名访问、安全配置。
- Tomcat 性能调优。
Tomcat 概念与运行原理
1. 概念
Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目。在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试程序的首选。可以利用Tomcat响应前端页面访问的请求。Tomcat是Apache服务器的扩展,但在运行时它是独立运行的,即运行Tomcat时,它实际作为一个Apache独立进程单独运行。
通过2023年4月份NetCraft排行榜可以产出Apache在服务器端开始占有很高的市场份额和第一个网站活跃度。
2. 运行原理
Tomcat结构图:
Server服务器:指代Tomcat服务器,包含Service多个组件。负责管理和启动Service服务。监听8006端口客户端的shutdown命令用于关闭Server服务器。
Service服务:由Tomcat进行封装,对外提供基于组件的web服务。主要包含Connectior核心组件、Container核心组件、Jasper、Naming等多个其它组件。各个Service服务是独立的,但是共享同一个JVM资源。
Connector核心组件:与外部环境的一个连接器,监听固定的端口接收外部请求,并进行处理返回。
Container核心组件:是Servlet容器,内部由多层容器组成,用于管理Servlet容器声命周期和调用Servlet相方法处理对应的业务逻辑。
Jasper组件:主要是将JSP文件转化为Java文件,并编译成.class文件。
Naming组件:命名符是将名称与对象绑定,使得可以通过名称访问对象。
Session组件:管理和创建Session、以及Session持久化。可自定义,支持Session集群。在服务器中开辟的内存空间,使用Session存储临时信息。
loging组件:记录相关的日志,错误日志,运行信息。
JMX组件:Java SE中定义的规范,主要是为应用程序、设备、系统等植入管理功能的框架,通过JMX可以远程监控Tomcat的状态。
通过上述Tomcat结构图可以发现,Tomcat服务器主要的组件由两个:Connector核心组件和Container核心组件。
Connector核心组件:职责接收客户端连接和加工处理客户端请求。每一个Connector对一个端口进行监听,接受request、返回response。
Container核心组件:所有子容器的父接口,属于责任链设计模式。在Container中包含四个子容器Engine、Host、Context、Wapper。最内部是Servlet。
- Engine容器:用来管理多个站点,但一个Service只能对应一个Engine。
- Host容器:代表一个站点,也可以称为虚拟主机。
- Context容器:代表应用程序,相当于一个war包。
- Wapper容器:封装了Servlet。
Host容器和Context容器的区别就是:Host对应的是一个站点的根目录下的程序,可以直接通过上级路径访问。Context容器代表该站点下除了根目录外其它的应用程序,访问时,除了上级目录外还需要加入相对于它的特定唯一标识路径。
Server处理HTTP请求过程:
请求顺序:客户端请求 -> Connector组件 -> Container组件 -> Engine组件 -> Host组件 -> Context组件 -> Wapper组件。
响应顺序:Wapper组件处理结果 -> Context组件 -> Host组件 -> Engine组件 -> Container组件 -> Connector组件 -> 客户端。
Tomcat 环境搭建
使用TomCat需要具备JDK环境,所以,需要先安装JDK环境
安装信息:JDK1.8以上,Tomcat 10.1.15
1. Windows环境下搭建Tomcat
JDK环境安装步骤:
步骤1:下载JDK安装包
下载JDK1.8页面:Java Downloads | Oracle
下载JDK21或者JDK17页面:Java Downloads | Oracle 中国
步骤2:下载完成之后,双击.exe文件,直接一直下一步即可
步骤3:安装完成之后,找到安装JDK的根目录,进入环境变量,设置JDK的环境信息
- 创建JAVA_HOME变量,并设置值为刚才安装的JDK的根目录。
- 找到Path变量,并新建一个值为
;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
。 - 创建一个CLASSPATH变量,并设置值为
.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
。
上述的变量根据实际情况进行创建,在JDK1.8以后的版本中,可以不进行配置CLASSPATH变量。
步骤4:配置完成之后进入cmd命令提示符窗口,输入java -version
查看当前安装版本信息
至此,JDK环境安装成功。
TomCat环境安装:
步骤1:下载Tomcat安装包
下载Tomcat 10.1.15界面:Apache Tomcat® - Apache Tomcat 10 Software Downloads
步骤2:解压下载完成的Tomcat安装包
解压之后的目录如下所示:
步骤3:进入bin目录,双击startup.bat,启动Tomcat
由于Tomcat的字符集编码为UTF-8,如果Windows系统的字符集编码不是UTF-8的话,弹出的命令行窗口则会显示乱码。
查看本机的字符集编码:进入cmd命令提示符窗口输入chcp
,如果提示“活动代码页:936” 则其编码格式为GBK(GB2312),其它活动页代码请自行查找。
步骤4:进入conf目录下,找到logging.properties,查找并替换所有的UTF-8为GBK
替换之前文件配置部分截图:
步骤5:再次进入bin目录,双击startup.bat,启动Tomcat
启动Tomcat的日志如下:
步骤6:进入浏览器访问localhost:8080端口
出现如下界面,则为安装Tomcat环境成功:
至此Tomcat环境安装成功。
2. Linux环境下搭建Tomcat
JDK环境安装步骤:
步骤1:下载JDK安装包
下载JDK1.8页面:Java Downloads | Oracle
下载JDK21或者JDK17页面:Java Downloads | Oracle 中国
步骤2:下载tar.gz文件,上传并解压文件tar.gz文件,并记录当前JDK的根路径
步骤3:编辑~/.bash_profile文件,配置JDK环境信息
export JAVA_HOME=JDK路径信息
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
步骤4:输入source ~/.bash_profile
命令,生效配置,输入java -version
查看JDK信息
至此,JDK环境安装成功。
TomCat环境安装:
步骤1:下载Tomcat安装包
下载Tomcat 10.1.15界面:Apache Tomcat® - Apache Tomcat 10 Software Downloads
步骤2:下载tar.gz文件,上传并解压文件tar.gz文件,并记录当前Tomcat的根路径
tar -zxvf apache-tomcat-10.1.15.tar.gz
解压之后的目录如下所示:
此目录结构基本上与Windows环境下的目录结构一致。
步骤3:进入bin目录,输入startup.sh
启动命令,启动Tomcat
步骤4:进入logs目录,查看catalina.out文件,看Tomcat启动日志/运行时日志
步骤5:进入浏览器访问服务器对外IP:8080端口
出现如下界面,则为安装Tomcat环境成功:
至此Tomcat环境安装成功。
Tomcat目录结构说明
名称 | 含义或用途 |
---|---|
bin | Tomcat运行命令: .sh结尾的是Linux命令,.bat结尾的是Windows命令。 常用命令:startup、shutdown、catalina(内存和字符集) |
conf | Tomcat配置文件: catalina.policy:防止JSP代码或用户代码破环Tomcat服务器。 catalina.properties:不能被JSP或者Server修改的空间列表。 context.xml:被所有Web服务都使用的文件,默认web.xml文件位置。 logging.properties:Tomcat日志使用的配置文件。 server.xml: Tomcat启动时,构建Tomcat容器。 tomcat-user.xml:Tomcat的Web页面人员或者管理员的配置信息。 web.xml: 被所有Web服务都使用的文件,启动页等。 |
lib | 所有Tomcat使用的Jar包和所有程序共享的Jar包 |
logs | 存放Tomcat运行期间产生的日志信息: Windows环境下输入日志在catalina.日期.log文件中,Linux环境下输入的日志在catalina.out文件中 |
temp | 存放Tomcat运行时产生的临时文件 |
webapps | 存放应用程序,在Tomcat启动时,会读取此目录下的所有War包、Jar包、文件夹 |
ROOT | Tomcat的根目录,可以直接访问此目录下的所有资源 |
work | Tomcat运行后编译后的文件,清空work目录和重启Tomcat即为Tomcat缓存 |
Tomcat 配置详情
1. 常用配置项修改
1.1 修改Tomcat端口号
端口号的范围:1~65535。
Tomcat默认会监听两个端口号:8005监听shutdown、8080监听HTTP连接。除此之外,还有一个8009监听AJP,服务器之间通讯时使用。
步骤1:进入conf目录,找到server.xml配置文件,修改8080监听HTTP连接的端口号
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
/>
步骤2:重启Tomcat服务器
1.2 修改Tomcat内存
JAVA内存模型:
- 堆内存:类的实例、数组等引用数据类型。JVM分配最大为内存的1/4,最小为内存的1/64。
- 栈内存:局部变量、方法参数。
- 静态内存区(持久区,不会被GC回收):常量、静态变量、类的元数据。
内存溢出异常:
- OutOfMemoryError:Java heap space异常,异常:堆内存满了,调整堆内存大小。
- OutOfMemoryError:PermGen space异常,异常:静态内存区满了,加载的类太多。
- StarkOverflowError异常,异常:栈内存满了,死循环或者递归。
步骤1:进入bin目录,找到catalina或者startup文件,进行配置如下内容
JAVA_OPTS="-server -Xms256m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"
步骤2:重启Tomcat服务器
1.3 Tomcat热部署
方式一:直接将war包放置到webapps目录下。
方式二:在server.xml配置文件中,加入Context标签。
<Context debug="0" docBase="war包路径" path="项目后的路径" reloadable="true" />
- debug:项目输出日志,数值越大,日志越详细。
- docBase:war包的路径,可以是绝对路径,也可以是相对路径,相对于webapps文件的路径。
- path:项目启动后,端口后、接口前的路径信息。
- reloadable:true - 自动重新加载war包新增或者改变的class文件。
方式三:conf目录的catalina文件夹下创建一个xml文件夹,并添加下述信息。
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="war包路径" reloadable="true" />
与方式二类似,只不过是单独配置文件,path路径和xml文件名相同。
1.4 数据库连接池与数据源
数据库的访问流程:加载驱动 -> 创建连接 -> 执行SQL -> 释放连接。
由数据库的访问流程可知,只有在执行SQL时存在差异化,其余步骤均是相同或相似的。所以为了避免性能损耗,创建一个专门的空间来存放数据库访问的连接。
Tomcat在7.0之前是使用DBCP,单线程的。在7.0之后使用jdbc,提高数据库访问连接的性能。
在java程序中使用Tomcat连接:
步骤1:创建一个Maven工程,在pom中引入tomcat-jdbc和MySQL的连接依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>10.1.15</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
步骤2:在MySQL数据库中创建一个demo数据库,并创建一个user数据库表,至少包含name字段
CREATE DATABASE `demo`;
CREATE TABLE `user` (
`id` bigint NOT NULL COMMENT '主键ID',
`NAME` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
步骤3:创建一个Demo类,在main方法中写入如下代码逻辑
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) throws Exception {
PoolProperties p = new PoolProperties();
// 数据库连接URL
p.setUrl("jdbc:mysql://localhost:3306/demo?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
// 数据库连接驱动
p.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 数据库用户名
p.setUsername("root");
// 数据库密码
p.setPassword("ZYMzym111");
// 是否将连接注册到JMX中
p.setJmxEnabled(true);
// 是否被空闲连接回收期进行检测
p.setTestWhileIdle(false);
// 是否在连接池中取出连接前进行检查
p.setTestOnBorrow(true);
// SQL查询
p.setValidationQuery("SELECT 1");
// 是否在归还前进行检查
p.setTestOnReturn(false);
// 设置验证频率
p.setValidationInterval(30000);
// 回收期休眠时间
p.setTimeBetweenEvictionRunsMillis(30000);
// 最大活动连接
p.setMaxActive(100);
// 初始化连接
p.setInitialSize(10);
// 最大等待时间
p.setMaxWait(10000);
// 最小空闲连接数
p.setMinIdle(10);
// JDBC拦截器
p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
// 数据操作
DataSource dataSource = new DataSource();
dataSource.setPoolProperties(p);
Connection connection = null;
try {
connection = dataSource.getConnection();
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery("select * from user limit 10");
int count = 1;
while (rs.next()) {
System.out.println((count++) + " : " + rs.getString("NAME"));
}
rs.close();
st.close();
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception e) {
}
}
}
}
}
步骤4: 运行测试结果
在Tomcat里面使用:
步骤1:进入conf目录,找到context.xml,配置Resouce信息
<Rescource name="jdbc/user"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterVal="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="root"
password="ZYMzym111"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/demo?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"/>
步骤2:进入conf目录,找到web.xml,配置全局的匹配项
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/user</res-ref-name>
<ref-type>javax.sql.DataSrouce<ref-type>
<ref-auth>Container</ref-auth>
</resource-ref>
步骤3:进入lib目录,放入MySQL的连接驱动的jar包
步骤4:重新启动Tomcat
2. web管理界面
在启动Tomcat之后,访问localhost:8080出现Tomcat首页的管理界面,管理主要是Server status、Manager App和Host Manager。
- Server Status:服务器状态。
- Manager App:应用管理。
- Host Manager:主机管理。
第一次点击的时候需要配置用户认证信息,进入conf目录,找到tomcat-users.xml文件,配置登录信息。
<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>
Manager App界面部署应用程序:
在部署项目过程中可能应用程序文件比较大,而Manager App页面部署过程中,有限制上传文件大小,默认50M,修改方式如下:
步骤1:进入webapps\manager\WEB-INF目录下,找到web.xml配置文件,修改multipart-config配置参数。
<multipart-config>
<!-- 50 MiB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
步骤2:重启Tomcat服务器
3. 单点登录配置
单点登录(Single Sign On),简称SSO,是目前比较流程的企业业务整合的解决方案之一。
SSO是再多个应用系统中,用户只需要登录一次就可以访问所有的相互信任的应用系统。
单点登录的原理图:
下述将通过Tomcat和CAS进行实现单点登录,略
4. 多域名访问
为了提高资源的利用率
基于IP地址的多域名访问:
步骤1:进入conf目录,找到server.xml文件,添加Host标签配置
<Host appBase="app包所在的目录" autoDeploy="true" upackWARs="true" name="名称">
<Context path="" docBase="." debug="0"/>
</Host>
步骤2:重启Tomcat服务器
访问地址有原本的IP地址:端口,改为名称:端口。
如果访问出错,加载失败,可能需要在环境的配置文件中,配置地址映射名称。
基于端口的多域名访问:
步骤1:进入conf目录,找到server.xml文件,添加Service标签配置
<Service>
<Contector connectionTimeout="20000" port="新端口" protocol="HTTP/1.1" redirectPort="443">
<Engine name="second" debug="0">
<Host appBase="app包所在的目录" autoDeploy="true" upackWARs="true" name="localhost">
<Context path="" docBase="." debug=""/>
</Host>
</Engine>
</Contector>
</Service>
步骤2:重启Tomcat服务器
访问地址有原本的IP地址:端口,改为IP地址:新端口。
如果访问出错,加载失败,可能需要检查环境防火墙是否开通新的端口。
5. 安全配置
Tomcat投入生产前的初始化配置:
- 关闭服务器端口
- 隐藏版本信息
- 禁用Tomcat管理页面
- 自定义错误页面
- AJP端口管理
- 启用cookie的HttpOnly
安全规范
5.1 关闭shutdown端口
为了防止通过Telent 8006端口输入SHUTDOWN命令来停止Tomcat服务器
步骤1: 进入conf目录,找到server.xml配置文件,更改Server标签中shutdown的值
<Server port="8006" shutdown="SHUTDOWN">
</Server>
步骤2:重启Tomcat服务器
5.2 修改Tomcat版本号
为了避免某些针对特定版本的Tomcat的攻击手段
步骤1:进入lib目录,找到catalina.jar,进入jar包内部一次org -> apache -> catalina -> util目录,看到ServerInfo.properties文件,修改改文件的server.info的值
步骤2:重启服务器
5.3 禁用Tomcat管理界面
为了防止通过Tomcat管理界面对服务做一些操作
步骤1:进入webapps目录,创建一个空的ROOT目录
步骤2:重启服务器
5.4 自定义错误页面
为了界面更加友好的提示,需要对一些常见的错误码做一个对应的错误页面
步骤1:进入webapps目录,将错误页面放置到ROOT目录下
步骤2:进入conf目录,找到web.xml文件,配置对应错误页面标签
<error-page>
<error-code>400</error-code>
<location>/400错误页面.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404错误页面.html</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/401错误页面.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500错误页面.html</location>
</error-page>
步骤3:重启服务器
5.5 AJP端口管理
AJP主要为了Tomcat和Http服务器通信定制的协议,提供比较高的通信速度和效率。
只有在前端使用Nginx代理时可以注释掉,如果是Apache时,必须要有这个。
步骤1:进入conf目录,找到server.xml文件,注释掉Connector标签,标签如下所示
<Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />
步骤2:重启服务器
5.6 修改Cookies安全性
主要是保存客户端的纯文本文件,例如离线购物车。
设置Cookies的只读属性可以防止XSS-跨站脚本攻击,潜入恶意的HTML代码
步骤1:进入conf目录,找到context.xml文件,给Context标签加入useHttpOnly属性
<Context useHttpOnly="true">
</Context>
步骤2:重启服务器
5.6 安全规范
账号管理、认证授权:
- 共享账号和无关账号的控制:创建有权限和角色的账户,产出无关权限的账户控制。
- 口令密码:静态口令认证,至少8位,包括数字、小写、大写、特殊字符,一般控制有效期90天以内。
- 用户权限:根据用户的需求,配置最小权限。
日志配置操作:
登陆使用的账号、登陆是否成功、登陆时间、远程登录的IP地址
步骤1:进入conf目录,找到server.xml文件,打开value标签,标签内容如下所示
<value classname="org.apache.catalina.values.AccessLogValue" Directory="logs" Prefix="localhost_access_log." Suffix=".txt" Pattern="common" resloveHosts="false"/>
步骤2:重启服务器
设备其他设置操作:
定时登出系统,在server.xml文件中,找到Connector标签的connectionTimeout属性,修改其对应的值
Tomcat 性能调优
除了内存和线程池的优化外,缓存优化和运动模式
缓存优化:
传输的后端服务器前,可以通过前端Nginx进行压缩,Tomcat开启gzip进行压缩。
运动模式:
- BIO:Tomcat 7以下默认模式,性能很低,一个线程只能处理一个请求。
- NIO:基于缓存区、非阻塞的I/O,并发性能较好。
- APR:Tomcat 7及以上默认模式,通过操作系统解决异步I/O
评论区