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
- Ffmpeg解析media容器过程/ ffmpeg 源代码简单分析 : av_read_frame()
ffmpeg 源代码简单分析 : av_read_frame() http://blog.csdn.net/leixiaohua1020/article/details/12678577 ffmpeg ...
- 曹工说Redis源码(2)-- redis server 启动过程解析及简单c语言基础知识补充
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
- spring mvc 启动过程及源码分析
由于公司开源框架选用的spring+spring mvc + mybatis.使用这些框架,网上都有现成的案例:需要那些配置文件.每种类型的配置文件的节点该如何书写等等.如果只是需要项目能够跑起来,只 ...
- CentOS7中Tomcat的安装和配置以及启动配置tomcat。启动过程中的易错点
Tomcat运行需要设置JRE目录,全局变量配置,请参见: Linux下JDK的安装和配置 当然也可以直接修改Tomcat的配置文件,请自行度娘 1.下载并解压 请先去官网找到需要下载的tom ...
- u_boot启动过程中的具体分析(1)
闭上眼睛,细致的回顾一下从NAND FLASH 启动的整个流程,首先,当我们打开板子的时候,先执行的就是嵌入在芯片上的iROM,它的作用就是为了把.NAND Flash 中的bootloader的一部 ...
- Android应用程序启动过程(二)分析
本文依据Android6.0源码,从点击Launcher图标,直至解析到MainActivity#OnCreate()被调用. Launcher简析 Launcher也是个应用程序,不过是个特殊的应用 ...
- Spring MVC源码(一) ----- 启动过程与组件初始化
SpringMVC作为MVC框架近年来被广泛地使用,其与Mybatis和Spring的组合,也成为许多公司开发web的套装.SpringMVC继承了Spring的优点,对业务代码的非侵入性,配置的便捷 ...
- uboot总结:uboot配置和启动过程2(mkconfig分析)
说明:文件位置:在uboot的目录下,文件名为:mkconfig.本身是一个脚本文件. 它的主要作用的是: (1)创建一个重要的符号链接 (2)创建一个config.mk文件(在include目录下) ...
- tomcat 5 启动过程官方文档
http://tomcat.apache.org/tomcat-7.0-doc/architecture/startup/serverStartup.txt Licensed to the Apach ...
随机推荐
- ip地址0.0.0.0与127.0.0.1的区别(转载)
原文链接:http://blog.csdn.net/ttx_laughing/article/details/58586907 最近在项目开发中发现一个奇怪的问题,当服务器与客户端在同一台机器上时,用 ...
- Python进阶-继承中的MRO与super
Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...
- 【Android Developers Training】 27. 序言:和其它应用交互
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- Redis事务原理分析
Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...
- ASP.NET MVC Autofac依赖注入的一点小心得(包含特性注入)
前言 IOC的重要性 大家都清楚..便利也都知道..新的ASP.NET Core也大量使用了这种手法.. 一直憋着没写ASP.NET Core的文章..还是怕误导大家.. 今天这篇也不是讲Core的 ...
- 基于Json序列化和反序列化通用的封装
1. 最近项目已经上线了 ,闲暇了几天 想将JSON的序列化以及反序列化进行重新的封装一下本人定义为JSONHelp,虽然Microsoft 已经做的很好了.但是我想封装一套为自己开发的项目使用.方便 ...
- [jbdj]SpringMVC框架(3)映射器
映射器:什么样的请求交给Action. 1} class : BeanNameUrlHandlerMapping 要掌握, 将程序员定义的Action所对应的<bean>标签的nam ...
- epii.js简约而不简单的JS模板引擎
epii.js是什么 epii.js是一个 模板引擎,可快速实现数据与ui绑定,快速实现事件绑定,与处理,不依赖任何第三方库,仅仅8k,在native+webapp开发 和 web开发,h5微网页上均 ...
- 字符的读写函数:fgetc()和fputc()
fgetc(); 功能: 从文件中读取字符. 头文件: #include <stdio.h> 函数原型:int fgetc(FILE *stream); 返 ...
- php与MySQL(基本操作)
PHP连接 MySQL 在我们访问 MySQL 数据库前,我们需要先连接到数据库服务器,连接服务器,我们使用mysqli_connect()函数. 在使用这个函数之前,我们首先来看一下这个函数的语法: ...