从服务器说起,一台装了操作系统(linux、unix、win等等)的物理机或者虚拟机不能称之为真正的服务器,因为服务器是能对外界提供服务的计算机,要能成为服务器必须借助其他软件的支持比如:tocmat、apache、IIS、nginx、jetty等等,借助与这些软件才能实现计算机具有服务的功能,下面我们谈谈web的开发中常用的服务器Tomcat。
一.从server.xml说起
从配置文件中我们可以看出:
1.一个tomcat只有一个server(主要提供整个与tomcat运行相关的环境)
2.一个server可配置多个Listener(相当于异步监听事件)
3.一个server配置一个GlobalNamingResources(JNDI映射,没用过,下面可以配多个resourse),统一的映射管理,避免每个servlet都需要配置,说实话,没用过不知道干啥用。
4.一个server配置多个service,虽然给的样例中是一个,但事实上可以配置多个,比如我们需要在一个tomcat下部署多个web服务,并且每个服务之间相互不影响,最长见的就是不使用相同的端口。
5.一个service可配置多个connector,connector就是链接,客户端的访问必须有链接才能实现,链接可以是不同的端口,不同的协议,也就是port和protocol,一般protocol都是HTTP/1.1,也会改成其他的比如apr,tomcat7默认使用bio,8.5使用nio,只有优化的时候才需要更改,关于AJP/1.3可以不用开启,它是为了适配其他服务器(比如Apache服务器,IIS服务器)的使用的协议。
6.一个service最多只能有一个Engine(没有验证),就是servlet处理器的一个实例。
7.realm就是一个安全上下文,主要是处理用户角色关系,我也知道有啥用。
8.一个engine可以配置多个host,一个host就代表一个宿主机,相当于不同的路径放的war,用不同的host访问。
至此一个基本的配置文件就介绍完了
二.核心组件
借用网上的图
tomcat的核心组件就两个:Connector和Container
Connector:连接器
其主要作用就是接受客户端的请求,将请求组装成request和reponse,然后创建线程给Engine处理。connector可以定义多个,常见的有HTTP,SSL,AJP和proxy(JK),后面两个不常用,它有许多设置属性(可以看我的TOMCAT优化里面有说明),我们常用的就是port和protocol(协议相关)。
Container:容器
这里的容器就是servlet容器,它上面运行着Engine,通常我们的war(也就是应用)就是在这里运行的。
具体说下两个核心组件:
Connector:
连接器的核心是ProtocolHandler,也就是处理器,它负责了连接器中的接受请求整理成request和response。
endpoint:包含了Acceptor、handler和异步超时检查。acceptor监听请求,交由handler来处理,endpoint实现了传输层TCP/IP协议,因为其接受的是socket,此时请求还未被封装,封装是在下一步进行的。
Processor:当执行到Processor时,processor会将socker包装成request,所以这里processor就需要实现应用层协议HTTP,最终将封装好的请求交由Adapeter处理。
Adapetr:adapetr的主要作用就是根据请求寻找适配后交由Container处理。
Container:
Container采用的是责任链的模式,即其下的组件(子容器)是包含关系,一个Engine可以对应多个host(也就是过个虚拟主机ps:这里的虚拟主机只的就是一个网站,比如一个webapp,webapp1,webapp2对应不同的网站不同的虚拟主机,可以通过与之对应一个域名或者ip的方式访问,这个不要和虚拟机混淆) ,而我们通常说的一个应用实时上对应的是Host中的一个Context,一个host下可以有多个context,比如淘宝,它下面可能会有订单、用户、仓库等等的不同的应用,那么一个应用对应的就是一个context简单的说就是一个web.xml,比如我们的应用名就是一个context-path,而我们的应用下可能存在多个servlet,所以就会有多个wrapper。对于tomcat而言,其实Context不是必须的,因为有时候纯静态的文件比如css、html等就不需要Context。再给一副图理解一下
总结一下就是:
(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
(2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
(3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封装着一个Servlet
整理下关系:
server:
service1:
Connector1:
ConnectorN:
Container:
Engine:
host1:
context1:
wrapper1:
servlet
wrapperN:
context1N:
hostN
serviceN:
Container是怎样处理请求的:
Pipeline-Valve(责任链,也可以理解为管道),责任链可能大家不太理解,说管道大家肯定知道,就是流式处理,上一步处理完成才能进行下一步,也可以理解为有顺序的同步,但是这里的责任链中有一点点不同就是,它的每一个容器最后都加了一个BaseValue,分别是StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve
上层管道执行到最后会执行自己的basevalue,此时basevalue会调用下级管道,如此依次执行直到执行到wrapper的basevalue,此时,StandardWrapperValue会创建于servlet相关的FilterChain这个我们可能比较熟悉,它是过滤链,应用中经常会用到的过滤器就是在其中运行的。当执行完所有的Filter的doFilter和servlet的service方法之后一个请求就算被处理完成了,最后将处理结果返回给Connector,Connector按socket返回给客户端。
以上就是对TOMCAT结构及原理不算特别细致的介绍,如有不对的欢迎指出,我们共同学习。