Tomcat 是 Apache 软件基金会(Apache Software Foundation)的一个开源项目,实现了 Servlet 及 JSP 规范,可以用来部署 WEB 应用及 WebService;本文主要介绍其基本概念。
1、Tomcat 安装
安装 Tomcat 之前需要先安装 Java,并设置 $JAVA_HOME 环境变量,Linux bash 环境下可按如下方式设置:
export JAVA_HOME=/home/mongo/soft/jdk1.8.0_321
下载 Tomcat 安装包,https://tomcat.apache.org/download-80.cgi,这里下载 Tomcat 8 的 zip 格式安装包,解压:
unzip apache-tomcat-8.5.85.zip
启动:
cd bin
./startup.sh
2、Tomcat 目录结构
Tomcat 解压后的目录为 Tomcat 根目录,使用 $CATALINA_HOME 表示;根目录下有如下目录:
bin:存放启动、关闭和其他脚本
conf:存放配置文件及相关 DTD
logs:存放日志文件
lib:jar 包存放目录
temp:临时文件目录
webapps:应用程序部署目录
work:Tomcat 工作目录,如存放 JSP 编译后的类文件
3、Tomcat 配置文件
Tomcat 配置文件存放在 $CATALINA_HOME/conf 下:
server.xml: Tomcat 核心配置文件,包含 Service、Connector、Engine、Realm、Valve、Hosts 等组件的相关配置。
context.xml:此文件为所有的 webapps 提供默认配置,每个 web 应用可以有自己的 context.xml,其存放位置为 META-INF 目录。
web.xml:此文件为所有的 webapps 提供默认部署相关的配置,每个 web 应用也可以使用自己的 web.xml 来覆盖全局的 web.xml。
tomcat-users.xml:用于配置管理 Tomcat 的角色、账号及密码。
catalina.policy:当使用 security 选项启动 Tomcat 时,用于为 Tomcat 设置安全策略。
catalina.properties:Tomcat 环境变量的配置,用于设定类加载器路径,以及一些与JVM调优相 关参数。
logging.properties:Tomcat 日志相关的配置,可以修改日志级别和日志路径等。
4、Tomcat 架构
Tomcat 可以按功能划分许多不同的组件,这些组件都可以在 conf/server.xml 文件中定义和配置;组件可分为四类:
1、顶级组件:位于配置层次的顶级,彼此间有着严格的对应关系,有 Server 及 Service组件;
2、连接器:连接客户端请求至 Servlet 容器,只有 Connector 组件;
3、容器:处理传入请求并创建响应的组件;Engine 处理 Service 的所有请求,Host 处理特定虚拟主机的所有请求,Context 处理特定 web 应用的所有请求;
4、被嵌套的组件:位于一个容器当中,但不能包含其它组件;一些组件可以嵌套在任何 Container 中,而另一些只能嵌套在 Context 中;
4.1、Server
Server(服务器)表示 Tomcat 的一个实例,它位于 conf/server.xml 的最外层,通常一个 JVM 只能包含一个 Tomcat 实例。默认配置表示在 8005 端口接收 shutdown 命令,且仅允许通过本机访问。
4.2、Service
Service(服务)主要用于关联 Engine 和 Connector,每个 Connector 通过一个特定的端口和协议接收请求,并将其转发至关联的 Engine 进行处理。因此,Service 包含一个 Engine、一个或多个Connector;而一个 Server 可以包含多个 Service,但通常情下一个 Server 只配置一个 Service。通常需要给 Service 命名,方便管理员在日志文件中识别不同的 Service。默认配置中 Server 只包含一个名为”Catalina"的 Service,而 Service里包含两个 Connector,其中一个监听 8080 端口接收 HTTP 请求,另一个监听 8009 端口接收 AJP 协议请求。
4.3、Connector
Connector(连接器)通过特定的端口接收特定协议的客户端请求,并将其转发至关联的 Engine 进行处理。一个 Engine 可以对应多个连接器,但必须使用不同的端口。连接器的常用属性如下:
1)、address:监听地址,默认为所有地址,即 0.0.0.0
2)、port:监听端口
3)、protocol:协议,默认为 HTTP/1.1
4)、URIEncoding:url 编码
5)、maxThreads:最大线程数,默认为 200
6)、minSpareThreads:最小保留的线程数
7)、maxSpareThreads:最大空闲线程数
8)、maxHttpHeaderSize:最大头大小
9)、redirectPort:如果连接器的协议是 HTTP,当客户端发来 HTTPS 请求时,则转发至此属性定义的端口
10)、connectionTimeout:客户端连接超时时间,单位为毫秒,默认为 60000,即 1 分钟
11)、enableLookups:是否允许通过 request.getRemoteHost() 进行 DNS 查询以获取客户端的主机名,默认为 true
12)、acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
连接器类型可以分为两种:
A、HTTP 连接器
HTTP 连接器表示支持 HTTP/1.1 协议的连接器组件,它使 Tomcat 能够作为独立的 Web 服务器。HTTP 连接器有三种不同的实现:Java Nio Connector、Java Nio2 Connector、APR/native Connector,它们的对比如下:
默认配置定义了一个协议为 protocol="HTTP/1.1" 的 Connector,表示根据环境自动选择具体的实现,也可以手动指定。
B、AJP 连接器
AJP 连接器表示通过 AJP(Apache JServ Protocol)协议与 Web 服务器通信的连接器。AJP 协议用于 Web 服务器和 Tomcat 之间传输数据,这比 HTTP 协议有更好的效率,但比较复杂不通用。通常用于将 Tomcat 集成到 Apache 服务器中,并且希望 Apache 处理静态内容或 SSL 连接的处理,即 Apache 服务器作为代理服务器。Apache 与 Tomcat 结合可以由 mod_jk 或 mod_proxy 模块来实现,但它们的使用范围不同:mod_jk 支持 apache/1.3,apache/2.0,mod_proxy 支持 apache/2.2+。默认配置了了一个监听 8009 端口的 AJP 连接器。
4.4、Engine
Engine(引擎)接收和处理来自一个或多个连接器的请求,并检查请求的 HTTP 头部信息以辨别请求应该发往哪个 Host 或 Context,并将完成的响应返回到连接器,以便最终传输回客户端。Engine 组件必须嵌套在 Service 组件内,它可以包含多个 Host 组件,还可以包含 Realm、Listener 和 Valve 等子容器。
Engine 常用属性:
1、name:Engine 名称
2、defaultHost:默认 Host
默认配置定义了一个名为"Catalina"的 Engine,而 Engine 里包含一个名为 “localhost” 的 Host,并被配置为默认虚拟主机。
4.5、Host
Host 表示一个虚拟主机,它是服务器的网络名称(例如"www.mycompany.com")与运行 Tomcat 的服务器的关联。为了使客户端能够使用 Tomcat 服务器的网络名称连接到 Tomcat 服务器,该名称必须在所属 Internet 域的域名服务(DNS)服务器中注册。一个 Engine 至少要包含一个 Host,在 Host 元素内可以嵌入与此虚拟主机关联的 Context 等元素。
Engine 常用属性:
1、name:虚拟主机名称;
2、appBase:web 应用程序目录
3、autoDeploy:是否自动部署,默认为 true
4、unpackWars:部署 war 包时是否先展开,默认为 true
默认配置定义了一个主机名为"localhost"的 Host,web 应用程序目录为 "webapps",自动部署程序,部署 war 包时先展开。
4.6、Context
Context(上下文)表示在特定虚拟主机中运行的 Web 应用程序,一个 Context 对应一个 Web 应用程序。Context 根据其定义的上下文路径(path)匹配请求,通过 docBase 找到 Web 应用程序部署目录,再由 web.xml 中定义的 servlet 选择一个合适的 servlet 处理传入的请求。一个 Host 可以有多个 Context,通常不建议定义在 server.xml 文件中,而是每个 Context 使用一个单独的 XML 文件定义,其存放目录为 $CATALINA_HOME/conf/<engine name>/<host name>。
server.xml 中默认没有定义 Context,但存在 conf/context.xml,它是部署在此 Tomcat 实例上所有 Web 应用程序的默认配置文件;通过它可以找到默认的和 Web 应用程序提供的部署描述符文件web.xml;conf/web.xml 定义了 Tomcat 提供的默认 Servlet 处理程序,主要用来处理静态资源请求;而各 webapp 的 Web.xml 可以定义其他的动态请求 Servlet 程序。
Context 常用的属性有:
1、docBase:Web 应用程序目录;可以使用相对路径,起始路径为此 Context 所属 Host 中 appBase 定义的路径;切记,docBase 的路径不能与相应的 Host 中 appBase 定义的路径有包含关系
2、path:相对于 Web 服务器根路径的 URI;如果 context 定义在一个单独的 xml 文件中,此属性不需要定义
3、reloadable:是否允许重新加载此 context 相关的 Web 应用程序的类;默认为 false
4.7、Realm
Realm 表示用户名、密码和分配给这些用户的角色(类似于Unix组)的“数据库”。Realm 的不同实现允许将 Catalina 集成到已经创建和维护了这种身份验证信息的环境中,然后利用该信息实现 Servlet 规范中所描述的容器管理的安全性。
一个 Catalina 容器(Engine、Host 或 Context)可以包含不超过一个 Realm 元素(Realm 本身可能包含多个嵌套的 Realm)。此外,与 Engine 或 Host 相关联的 Realm 将自动由较低级别的容器继承,除非较低级别的容器显式地定义了自己的 Reamlm。如果没有为 Engine 配置域,则会自动为 Engine 配置一个空 Realm。
定义 Realm 惟一必须提供的属性是 classname,用于表示此 Realm 认证的用户及角色等认证信息的存放位置,Tomcat 中实现了多种不同的 Realm,如下:
UserDatabaseRealm:基于 UserDatabase 文件(通常是tomcat-user.xml)实现用户认证,它是一个完全可更新和持久有效的 MemoryRealm,因此能够跟标准的 MemoryRealm 兼容
LockOutRealm:提供锁定功能,以便在给定时间段内出现过多的失败时提供用户锁定机制
JAASRealm:基于Java Authintication and Authorization Service 实现的用户认证
JDBCRealm:通过 JDBC 访问某关系型数据库表实现用户认证
JNDIRealm:基于JNDI 使用目录服务实现认证
MemoryRealm:查找 tomcat-user.xml 文件实现用户认证
默认配置定义了一个 LockOutRealm,该 Realm 嵌套一个 UserDatabaseRealm,通过 tomcat-user.xml 文件实现用户认证。
4.8、Valve
Valve 元素表示将被插入到相关 Catalina 容器(Engine、Host 或 Context)的请求处理管道中的组件。一个容器内可以建立多个 Valve,Valve 定义的次序决定了它们生效的次序。不同类型的 Valve具有不同的功能,Tomcat 中实现了多种不同的 Valve:
AccessLogValve:访问日志 Valve
ExtendedAccessValve:扩展功能的访问日志 Valve
RequestDumperValve:请求转储 Valve
RemoteAddrValve:远程地址 Valve
RemoteHostValve:远程主机名 Valve
SemaphoreValve:用于控制 Tomcat 任何容器上并发访问数量的 Valve
ReplicationValve:用于 Tomcat 集群架构的 Valve,可以在某个 session 信息发生更改时触发 session 数据在各节点间进行复制
SingleSignOn:用于单点登录的 Valve,即一次认证可访问所有设置在一起的 webapp
ClusterSingleSingOn:SingleSignOn 的扩展,用于 Tomcat 集群当中
默认配置中定义了一个 AccessLogValve 用来记录访问日志。
4.9、其他组件
1、Logger 日志记录器:用于记录组件内部的状态信息,可被用于除 Context 之外的任何容器中。日志记录的功能可被继承,因此,一个引擎级别的 Logger 将会记录引擎内部所有组件相关的信息,除非内部组件定义了自己的 Logger。
2、Listener:用于创建和配置 LifecycleListener 对象,而 LifecycleListener 通常被开发人员用来创建和删除容器。
3、Loader:Java 的动态装载功能是其语言功能强大表现之一,Servlet 容器使用此功能在运行时动态装载 servlet 和它们所依赖的类。
4、Resources:用于在 Context 中指定需要装载但不在 Tomcat 本地磁盘上的应用资源,如 Java 类,HTML 页面,JSP 文件等。
5、GlobalNamingResources:应用于整个服务器的 JNDI 映射,此可以避免每个 Web 应用程序都需要在各自的 web.xml 创建相应的资源,这在部署 WAR 形式的应用程序尤为有用。它通常可以包含三个子元素:Environment、Resource 和 ResourceEnvRef。
6、WatchedResource:用于 Context 中监视 webapp 文件的变化,在监视到文件内容发生改变时重新装载此文件。
7、Manager:用于实现 HTTP 会话管理功能,Tomcat 中有 5 种 Manger 的实现:
A、StandardManager:Tomcat6 的默认会话管理器,用于非集群环境 Tomcat 的会话管理。当 Tomcat 关闭时,会话数据会写入一个名为 SESSION.ser 的文件,并在 Tomcat 下次启动时读取此文件。
B、PersistentManager:当一个会话长时间处于空闲状态时会被写入到 swap 会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。
C、DeltaManager:属于 ClusterManager,用于 Tomcat 集群的会话管理,它通过将改变了的会话数据同步给集群中的其它节点实现会话复制。这种实现会将所有改变的会话同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。但集群节点较多时,会消耗大量的网络资源,一般适用于 3、4 个节点的集群。
D、BackupManager:属于ClusterManager,用于 Tomcat 集群的会话管理,与 DeltaManager 不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点。
E、SimpleTcpReplicationManager:Tomcat4 用到的会话管理器。
8、Stores:PersistentManager 包含一个 Store 元素以指定将会话数据存储至何处,通常有两种实现方式:FileStore 和 JDBCStore。
9、Cluster:用于配置 Tomcat 集群,可用于 Engine 和 Host 容器中。在用于 Engine 容器中时,Engine 中的所有 Host 均支持集群功能。在 Cluster 元素中,需要定义一个 Manager、一个 Channel 和 一个 ClusterListener。
10、Channel:Cluster 中节点通信的信道,Channel 中需要至少定义 Membership、Receiver 和 Sender 三个元素,此外还有一个可选元素 Interceptor。
11、Membership:Channel 中同一信道上集群组中的成员,监控加入当前集群中的节点并在各节点间传递心跳信息,在接收不到某成员的心跳信息时将其从集群节点中移除。
12、Sender:Channel 中的数据发送器,发送同步数据至集群中的其它节点。发送器内部可以定义一个 Transport 元素。
13、Transport:位于 Sender 内部,配置数据如何发送至集群中的其它节点。有两种 Transport 的实现:
A、PooledMultiSender 基于Java 阻塞式 IO,可以将一次将多个信息并发发送至其它节点,但一次只能传送给一个节点。
B、PooledParallelSener 基于Java 非阻塞式 IO,即NIO,可以一次发送多个信息至一个或多个节点。
14、Receiver:位于 Channel 内部,用于定义某节点如何从其它节点接收 Sender 发送的同步数据,有两种实现方式:BioReceiver 和 NioReceiver。