Tomcat结构、启动过程、关键组件简单分析
Tomcat
结构:
Tomcat最顶层容器叫Server,代表整个服务器,Server中包含至少一个Service,用于具体提供服务,Service主要包含:Connector和Container,前者处理链接并提供Socket与request和response的转换,Container用于封装和管理Servlet,以及具体处理request请求。
一个Tomcat里一个Server,包含多个Service,一个Service只有一个Container,可以有多个Connector。一个Container只有一个Engine,Engine里面可以有多个Host,每个Host(虚拟主机,站点)下可以有多个Context(代表一个应用),每个Context下可以有过个Wrapper(每个封装一个Servlet)。
Tomcat里的server由Catalina来管理,他是Tomcat的管理类,load(调server的init),start(调server的start,下同),stop三个方法管理服务器生命周期。
启动:
正常情况启动Tomcat就是调用Bootstrap的main方法,main,新建bootstrap,执行init初始化,并调用start。init里初始化classloader,由此创建Catalina实例,赋给catalinaDaemon变量。
bootstrap的start调用setAwait(true),load(args),start()三个方法,这三个方法又都调用Catalina的相应方法进行具体执行。在Catalina中,setAwait用于设置await属性的值,服务器启动之后据此判断是否进入启动状态,其load方法根据cong/server.xml创建了Server对象,并赋值给server属性,然后调用Server的init方法。其start方法主要调用了server的start方法去启动服务器。
Server接口中提供addService和removeService,server的init方法和start方法分别循环调用每个Service的init和start方法。 都是类似的一层一层的往下调用的。bootstrap-->Catalina-->Standardserver-->StandService-->Container-->MapperUstener-->Executer-->Connector.
生命周期管理:
Tomacat通过,org.apache.Lifecycle接口统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口,这个接口做了四件事:
1,定义了13个String类型的常量,用于LifecycleEvent时间的type属性中,作用是区分组件发出 事件时的状态(如初始化前、启动前、启动后等)。
2,定义了三个管理监听器的方法addLifecycleListener,findLifecycleListeners,
removeLifecycleListener,添加,查找和删除。
3,定义了4个生命周期方法:init、start、stop、destroy。
4,定义了获取当前状态的两个方法,getState,getStateName,分别获取当前的状态和String类型的状态的名字。
Container:
Container启动是被Service调用init和start方法;是Tomcat中容器的接口,一共有四个子接口(子容器),Engine、Host,Context,Wrapper和一个默认的实现类ContainerBase,这四个子容器都有一个对应的StandXXX实现类,都继承自ContainerBase,Base又间接继承LifecycleBase。
每个Service一个Container,一个Engine,Engine里面可以有多个Host,每个Host(虚拟主机,站点)下可以有多个Context(代表一个应用),每个Context下可以有过个Wrapper(每个封装一个Servlet)。
4种容器的配置:
Engine和Host都是在conf/server.xml文件中,context有三种方式,可以通过文件(server.xml,conf/engineName/hostName/应用名.xml,conf/context.xml等),还可以自己将war包放到host目录下,还可以将应用的文件夹直接放到Host目录下。
Pipeline-Value管道:
Container处理请求是使用Pipeline-Value管道来处理的:
Pipeline-value是责任链处理模式,责任链模式是指在一个请求的处理过程中有多个处理者依次对请求进行处理,这个是管道模型,和普通的责任链模型又有一点不同:1,每个pipeline都有特定的Value,在管道的最后执行,叫做baseValue,这个baseValue不可删除。2,在上层管道的baseValue中会调用下层容器的管道。类似多层次的快递运输和再分配再运输。
例如:Engine的管道中依次执行Engine的各个value,最后至此那个satandardEngineValue用来调用Host的管道……,知道最后执行wrapper管道中的StandWrapperValue。跟Filter中用到的FilterChain很相似,而Servlet就相当于最后的BaseValue。
Pipe-line管道的实现分为生命周期的实现和处理请求两部分:1,Container中的Pipe-line在抽象类ContainerBase中定义,并在生命周期的startInternal,stopInternal,destoryInternal方法中调用管道的相应的生命周期方法,2,Connector在接收到请求后会调用最顶层容器的Pipeline来处理,Pipeline调用所包含的Value的invoke方法来处理请求,并且在BaseValue中有调用了子容器Pipeline所包含value的invoke方法,直到最后调用了Wrapper的Pipeline所包含的BaseValue-StandWrapperValue,在其中创建Filter-Chain并调用期doFilter方法来处理请求,FilterChain包含着我们配置的请求相匹配的Filter和Servlet,其doFilter方法会一次调用所有的Filter的doFilter方法和Servlet的service方法,进而处理请求。
Connector分析:
Connector用于接受请求并将请求封装成Request和Response来具体处理,最底层使用Socket来进行连接的,Request和Response是按照Http协议来封装的,所以Connector同时实现了TCP/IP协议和http协议,Request和Response封装完之后交给container进行处理,Connector就是Servlet的容器,Container处理完之后返回给Connector,最后Connector使用Socket将处理结果返回给客户端。这样整个请求就完成了。注意这只是Tomcat的处理完成了,在Container内部封装的各个Servlet会进行进一步的处理。
Connector中具体是使用ProtocolHandler来处理请求,不同的ProtocolHandler代表不同的连接类型。ProtocolHandler有三个最为重要的组件:Endpoint,Processor,Adapter;Endpoint用于处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将封装好的Request交给Container进行具体的处理。也就是说:Endpoint用来实现TCP/IP协议,Processor实现HTTP协议,Adapter将请求适配到Servlet容器进行具体的处理。
Connector类本省的作用主要是在其创建时创建ProtocolHandler,然后在生命周期的相关方法中调用了Protocol的相关生命周期方法。内部的Processor在其process方法中会调用Adapter的service方法来处理请求,Adapter的service方法主要是通过调用Container管道中的invoke方法来处理请求。
//调用Container管道的代码
connector.getService().getContainer().getPipeline().getFirst().invoke(request,response);
这里首首先从Connector中获取到Service,然后从中获取Container,再获取管道,再获取管道的第一个value,最后调用invoke方法执行请求。Service中保存的是最顶层的容器,当调用最顶层容器管道的invoke方法时,管道将逐层调用各层容器的管道中的Value的invoke方法,知道最后调用Wrapper的管道中的BaseValue(StandardWrapperValue)来处理Filter和Servlet。
参考:《看透springMVC》
----名白
http://www.cnblogs.com/mingbai/p/TomcatAnalysis.html