Tomcat体系架构

317 阅读4分钟

Tomcat是一款开源轻量级的Web应用服务器,是一个优秀的Servlet容器实现。很多开发者对Tomcat的认识都是仅限于ide中跑起来,因此,本文从几个方面简单的剖析了Tomcat的体系结构,以便对Tomcat有个整体的认识。

快速上手

版本选择

8.5.x版本是在9.0出现以后发布的一个中间版本,主体架构延续8.0,同时又实现了部分9.0的新特性。

版本特点:

1.支持Servlet 3.1

Servlet2.X:项目目录结构必须要有WEB-INF,web.xml等文件夹和文件,在web.xml中配置servlet,filter,listener,以web.xml为java web项目的统一入口

servlet 3.x规范:项目中可以不需要WEB-INF,web.xml等文件夹和文件,在没有web.xml文件的情况下,通过注解实现servlet,filter, listener的声明,当使用注解时,容器自动进行扫描。

2.默认采用NIO,移除BIO

3.采用异步日志处理,性能有较大提升

因此,推荐使用Tomcat 8.5.x的版本。

启动方式

下载链接

将Tomcat下载到本地之后,就可以启动了。常见的两种启动方式:

1.一般启动

执行bin\下的startup即可,IDE也是封装了这个步骤。

2.嵌入式启动

利用Tomcat提供的接口直接通过方法调用,可以参考Spring Boot的启动方式。

启动之后,访问http://localhost:8080/即可进入Tomcat默认的Web应用界面。

项目部署

将开发好的Web项目部署到Tomcat中,有两种方式:

1.隐式部署

直接丢文件夹、war到webapps目录,Tomcat会自动将war转成文件夹。然后根据文件夹名称自动生成虚拟路径,重启Tomcat之后,访问http://localhost:8080/filesname即可进入。

2.显示部署

添加context元素

server.xml中的Host加入一个Context(指定路径和文件地址),例如:

显示的指定了一个war包的虚拟路径,通过该路径访问即可。

创建xml文件

在conf/Catalina/localhost中创建xml文件,访问路径为文件名,例如:

在localhost目录下新建demo.xml,内容为:

对这三种部署方式做一个总结:

隐式部署:可以很快部署,但是需要人手动移动Web应用到webapps下,在实际操作中不是很人性化。

添加context元素 : 配置速度快,需要配置两个路径,如果path为空字符串,则为缺省配置。每次修改server.xml文件后都要重新启动Tomcat服务器。

创建xml文件:服务器后台会自动部署,修改一次后台部署一次,不用重复启动Tomcat服务器。

值得注意的是,一般情况下会鼓励重启(JVM可能会在有新文件部署时产生错误)。

目录结构

将Tomcat解压之后就可以看到其目录结构,此处介绍最常用的几个:

1.bin

startup,主要是检查catalina.bat/sh 执行所需环境,并调用catalina.bat 批处理文件。

catalina,真正启动Tomcat文件,可以在里面设置jvm参数。

2.conf

server.xml : Tomcat最常用的配置文件,用于部署webapp。

web.xml : Tomcat中所有应用默认的部署描述文件,主要定义了基础的Servlet和MIME映射(mime-mapping 文件类型),如果部署的应用中不包含Web.xml,那么Tomcat将使用此文件初始化部署描述,反之,Tomcat会在启动时将默认描述与定义描述配置进行合并。

3.lib

对于所有的项目都公用的依赖文件,项目个性化定制通过Maven导入当前项目。

4.work

最终运行的文件,当客户端用户访问一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。

组件架构

看完了Tomcat的外壳,就应该了解一下它工作时的内部机制。先看一张结构图:

Tomcat中最顶层的容器是Server,代表着整个服务器。一个Server可以多个一个Service,每一个Service表示一个具体提供的服务。

Service主要包含两个部分:Connector和Container,它们的作用如下:

  1. Connector用于处理链接相关的事情,并提供Socket与Request和Response相关的转化;
  2. Container用于封装和管理Servlet,以及具体处理Request请求;

一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供http和https链接。那么,为什么要将连接和资源分开呢?

是为了将网络协议与容器解耦,无论采用什么协议,Connector都会将其封装成统一的接口来便于Container操作。

可以有多个Host与多个Context组件的这种设计是为了一个Tomcat能部署多个Web项目,目前也沦为了时代的遗产。在虚拟化技术大行其道的今天,采用的方式往往是创建多个虚拟主机,一个主机搭配一个Tomcat,一个Tomcat部署一个独立项目。