Tomcat是一个JSP/Servlet容器。
Tomcat浅谈
Tomcat是一个JSP/Servlet容器。其作为Servlet容器,有三种工作模式:独立的Servlet容器、进程内的Servlet容器和进程外的Servlet容器。
Tomcat总体结构
核心组件:Connector 和 Container。多个 Connector 和一个 Container 就形成了一个 Service。Service 只是在 Connector 和 Container 外面多包一层,把它们组装在一起,向外面提供服务,一个 Service 可以设置多个 Connector,但是只能有一个 Container 容器。
整个 Tomcat 的生命周期(通过实现Lifecycle实现)由 Server 控制,作用就是要能够提供一个接口让其它程序能够访问到这个 Service 集合、同时要维护它所包含的所有 Service 的生命周期,包括如何初始化、如何结束服务、如何找到别人要访问的 Service。
Connecter组件
- 接收客户端连接
- 加工处理客户端请求
负责接收浏览器的发过来的 tcp 连接请求,创建一个 Request 和 Response 对象分别用于和请求端交换数据,然后从线程池中取出一个线程来处理这个请求,并把产生的 Request 和 Response 对象传给处理这个请求的线程。Connector有三种IO处理模型BIO、NIO、AIO(APR)
注:启动过程:初始化SeverSocket, 初始化线程池,构建Request 和 Response,请求到来时,激活线程,解析http协议,把头写到Request 和 Response中,传给Container,完成之后返回Request 和 Response对象,关闭当前Socket,回收线程。
BIO、NIO、AIO适用场景分析:
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
Container组件
- 所有的子容器的父接口
Container 是容器的父接口,所有子容器都必须实现这个接口,Container 容器的设计用的是典型的责任链的设计模式,它有四个子容器组件构成,分别是:Engine、Host、Context、Wrapper,这四个组件不是平行的,而是父子关系,Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper。(子容器的路由放在request中)
Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器,Context是 Servlet 运行的基本环境,对应Web工程,定义在父容器 Host 中,Host 不是必须的,但是要运行 war 程序,就必须要 Host,因为 war 中必有 web.xml 文件,这个文件的解析需要 Host ,如果要有多个 Host 就要定义一个 top 容器 Engine 了。而 Engine 没有父容器了,一个 Engine 代表一个完整的 Servlet 引擎。
- 责任链设计模式
很多对象由每个对象对其下家的引用连接起来形成,请求在链上传递,这样可以不影响客户端而能够在链上增加任意处理节点。包含抽象处理者和具体处理者,整个容器就是通过一个链连接在一起,这个链一直将请求正确传递给最终处理的Servlet。(其中Pipeline和Value扩展了链的功能,使得可以接收外界干预)。
注:此外,还有命令模式,观察者模式,门面模式等。
其他组件
安全组件 security、logger 日志组件、session、mbeans、naming 等。这些组件共同为 Connector 和 Container 提供必要的服务。
Tomcat请求过程
- 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
- Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
- Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
- Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。
- path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。
- 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。
- Context把执行完之后的HttpServletResponse对象返回给Host。
- Host把HttpServletResponse对象返回给Engine。
- Engine把HttpServletResponse对象返回Connector。
- Connector把HttpServletResponse对象返回给客户Browser。
Tomcat目录
tomcat
|—bin:存放启动和关闭tomcat脚本
|—conf:存放不同的配置文件(server.xml和web.xml);
|—doc:存放Tomcat文档;
|—lib/japser/common:存放Tomcat运行需要的库文件(JARS);
|—logs:存放Tomcat执行时的LOG文件;
|—src:存放Tomcat的源代码;
|—webapps:Tomcat的主要Web发布目录(包括应用程序示例);
|—work:存放jsp编译后产生的class文件;
Tomcat配置文件
我们打开conf文件夹可以看到Tomcat的配置文件:
server.xml: Tomcat的主配置文件,包含Service, Connector, Engine, Realm, Valve, Hosts主组件的相关配置信息;
web.xml:遵循Servlet规范标准的配置文件,用于配置servlet,并为所有的Web应用程序提供包括MIME映射等默认配置信息;
tomcat-user.xml:Realm认证时用到的相关角色、用户和密码等信息;Tomcat自带的manager默认情况下会用到此文件;在Tomcat中添加/删除用户,为用户 指定角色等将通过编辑此文件实现;
catalina.policy:Java相关的安全策略配置文件,在系统资源级别上提供访问控制的能力;
catalina.properties:Tomcat内部package的定义及访问相关控制,也包括对通过类装载器装载的内容的控制;Tomcat在启动时会事先读取此文件的相关设置;
logging.properties: Tomcat6通过自己内部实现的JAVA日志记录器来记录操作相关的日志,此文件即为日志记录器相关的配置信息,可以用来定义日志记录的组 件级别以及日志文件的存在位置等;
context.xml:所有host的默认配置信息;