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,它们的作用如下:
- Connector用于处理链接相关的事情,并提供Socket与Request和Response相关的转化;
- Container用于封装和管理Servlet,以及具体处理Request请求;
一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供http和https链接。那么,为什么要将连接和资源分开呢?
是为了将网络协议与容器解耦,无论采用什么协议,Connector都会将其封装成统一的接口来便于Container操作。
可以有多个Host与多个Context组件的这种设计是为了一个Tomcat能部署多个Web项目,目前也沦为了时代的遗产。在虚拟化技术大行其道的今天,采用的方式往往是创建多个虚拟主机,一个主机搭配一个Tomcat,一个Tomcat部署一个独立项目。