侧边栏壁纸
博主头像
叩钉壹刻博主等级

7分技术,3分管理,2分运气

  • 累计撰写 28 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Tomcat服务配置与性能优化

鹿心肺语
2023-11-22 / 0 评论 / 0 点赞 / 13 阅读 / 35387 字

整体介绍

Tomcat服务器是一个免费开放源代码的Web服务器,轻量级应用服务器。为众多大规模任务关键性网络提供支持,适用于各种行业和组织。

本文中将通过以下内容,从各个方面去对Tomcat进行了解:

  • Tomcat 概念与运行原理。
  • Tomcat 环境搭建:Windows和Linux环境下搭建Tomcat。
  • Tomcat 配置详情:常用配置项修改、web管理界面、单点登录配置、多域名访问、安全配置。
  • Tomcat 性能调优。

Tomcat 概念与运行原理

1. 概念

Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目。在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试程序的首选。可以利用Tomcat响应前端页面访问的请求。Tomcat是Apache服务器的扩展,但在运行时它是独立运行的,即运行Tomcat时,它实际作为一个Apache独立进程单独运行。

2023年4月份NetCraft排行榜

通过2023年4月份NetCraft排行榜可以产出Apache在服务器端开始占有很高的市场份额和第一个网站活跃度。

2. 运行原理

Tomcat结构图

image-2020231023110430.png

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请求过程

image-2020231023115832

请求顺序:客户端请求 -> 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查看当前安装版本信息

image-2020231024091104

至此,JDK环境安装成功。

TomCat环境安装

步骤1:下载Tomcat安装包

下载Tomcat 10.1.15界面:Apache Tomcat® - Apache Tomcat 10 Software Downloads

步骤2:解压下载完成的Tomcat安装包

解压之后的目录如下所示:

image-2020231024092130

步骤3:进入bin目录,双击startup.bat,启动Tomcat

由于Tomcat的字符集编码为UTF-8,如果Windows系统的字符集编码不是UTF-8的话,弹出的命令行窗口则会显示乱码。

查看本机的字符集编码:进入cmd命令提示符窗口输入chcp,如果提示“活动代码页:936” 则其编码格式为GBK(GB2312),其它活动页代码请自行查找。

步骤4:进入conf目录下,找到logging.properties,查找并替换所有的UTF-8为GBK

替换之前文件配置部分截图:

image-20231024092956

步骤5:再次进入bin目录,双击startup.bat,启动Tomcat

启动Tomcat的日志如下:

image-2020231024093234

步骤6:进入浏览器访问localhost:8080端口

出现如下界面,则为安装Tomcat环境成功:

image-20231024093503

至此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信息

image-20231024094403

至此,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

解压之后的目录如下所示:

image-20231024094956

此目录结构基本上与Windows环境下的目录结构一致。

步骤3:进入bin目录,输入startup.sh启动命令,启动Tomcat

image-20231024095428

步骤4:进入logs目录,查看catalina.out文件,看Tomcat启动日志/运行时日志

image-20231024095652

步骤5:进入浏览器访问服务器对外IP:8080端口

出现如下界面,则为安装Tomcat环境成功:

image-20231024093503

至此Tomcat环境安装成功。

Tomcat目录结构说明

名称含义或用途
binTomcat运行命令:
.sh结尾的是Linux命令,.bat结尾的是Windows命令。
常用命令:startup、shutdown、catalina(内存和字符集)
confTomcat配置文件:
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包、文件夹
ROOTTomcat的根目录,可以直接访问此目录下的所有资源
workTomcat运行后编译后的文件,清空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。

image-20231025150823

  • Server Status:服务器状态。
  • Manager App:应用管理。
  • Host Manager:主机管理。

第一次点击的时候需要配置用户认证信息,进入conf目录,找到tomcat-users.xml文件,配置登录信息。

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

Manager App界面部署应用程序:

image-20231026140505

在部署项目过程中可能应用程序文件比较大,而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是再多个应用系统中,用户只需要登录一次就可以访问所有的相互信任的应用系统。

单点登录的原理图:

image-20231026231618

下述将通过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
0

评论区