当前位置: 移动技术网 > IT编程>开发语言>Java > 知识小罐头05(tomcat简单源码分析 上)

知识小罐头05(tomcat简单源码分析 上)

2018年12月19日  | 移动技术网IT编程  | 我要评论

天罗唐门输出宏,多维新闻网网址,说爱你蔡依林

  这一篇我们不看源码,就大概理一下tomcat内部组成部分!前面花费了两篇博客的篇幅来说说了一般的maven web项目并部署到tomcat运行,其实都是为这篇做铺垫的!

  其实我下载了tomcat7,tomcat8,tomcat9这三个版本的,但是tomcat9有个问题,就是启动的时候黑窗口出现中文乱码,试了很多方法都没用,改了tomcat9配置文件,改了cmd的编码utf8,去了注册表也改了tomcat的65001的那个,虽然都没什么用就对了,后面我看看能不能解决一下这个问题!

  我们还是以tomcat7为例,看看其中原理!

  注意:我说的内容可能会删减很多不怎么重要的内容,我们只关注核心原理,把核心的原理搞定了,再去研究那些细枝末节的东西会事半功倍!

  ok,进入正题,首先我们从tomcat的目录出发;

1.tomcat基本结构

  我们重点先看看conf文件夹,tomcat最主要的原理就在这里

 

  打开conf文件夹可以看到这么东西,我们只看关键的server.xml,这个配置文件搞清楚了,tomcat基本的组成部分也就ok了!

 

  打开server.xml,我删除了所有的注释以及感觉不怎么重要的东西!第一部分和第二部分就组成了tomcat的骨架

 

  第一部分是一个连接器,用于接受我们在浏览器发送的localhost:8080/xxx这个请求

  第二部分是处理请求的地方,将连接器接收的请求再放到这里处理;通常很多人就把这部分叫做container(就是容器的意思),其实这container是一个笼统的称呼,为了方便我们理解才这样说的!实际上配置文件中哪有container啊!(注:其实container是一个接口,这里engine,host,context等都实现了这个接口,所以才会把这整块地方叫做container

  所以,总的来说,tomcat分为两部分,一个接收请求的connector和处理请求的container!假如你还要说的简单一点,tomcat其实就是一个container,而这个container里面就是很多的servlet,将我们的请求交给这些servlet处理然后返回,所以tomcat本质上就是一个servlet容器!

  connector和container的关系就好像一个公司的前台和老板,外面的人想要跟老板说点什么肯定要经过前台,前台看你是个正常人才会帮你通知一下老板,不然五花八门的几十人都一下子跑到老板的办公室坐着,emmm...后果就不用多说了吧!

  下面我们就来仔细研究研究connector和container,只要把这两个研究清楚了,tomcat整个结构就清晰了!

 

2. connector内部结构

   其实从上面的connector标签可以看的出来一点端倪;这个连接器可以有多个,常用的就是处理http协议和ajp协议的,听说这个ajp的运用场景是:当tomcat服务器和其他的http服务器(例如apache)集成一起使用的时候,这个连接器就会生效;这个以后用到再说,我们现在只关注http的这个连接器

 

  只看http的连接器:

  在说connector内部结构之前,肯定能够想象得到connector内部到底干了什么事!首先肯定是要接收整个http请求,http请求里面就是一些请求头,请求空行,请求体这些东西组成嘛!想办法把这些东西解析一下,取出我们需要的一些信息,什么请求路径啊,ip啊,端口啊什么的等等,然后根据这些信息包装成reques,传到container进行进一步处理;

  下面用一个图来说明这个步骤:

  

  根据上图,可以看到connector内部有一个protocalhandler(协议处理器,种类有http11protocol用于普通的socket连接;http11nioprotocol用于niosocket连接;不了解的也不要深究,后面也许我会说一说bio,nio,aio的一些东西,看情况)

  而这个协议处理器内部大概分为三个部分,endpoint,processor,adapter(图上adapter可能拼错了,我也是随便找的图,没仔细看)。

  我们分析一下这三个东西是干什么的,那么这个connector的大概逻辑就出来了!

  endpoint:看到其中的acceptor就能知道,这个肯定是用来处理socket连接的,并且要实现tcp/ip协议;acceptor用来监听请求,然后handler(处理器)内部调用processor来处理接收的socket请求;不过这个东西比较底层了,有兴趣的小伙伴可以继续深究,这里就说到这里;

  processor:上一步说到handler内部调用这个processor去处理socket请求,怎么处理呢?其实就是将请求的一些数据拿出来,进行包装成一个普通的httprequest对象;而且这个processor要实现http协议;

  adaptor:上一步是包装成一个普通的httprequest对象,但是我们是做web应用,httprequest对象不是我们需要的,要继续包装成一个httpservletrequest对象,传到container中就可以使用或者看情况进一步处理;

 

3.container内部结构

   前面分析了一下connector的内部就够,其实就是根据socket连接接收请求,实现xxx协议,将请求中的数据最后封装成一个httpservletrequest对象,传到container;

  但是传到container中又经过了什么处理呢?

  我们可以继续想象一下内部干了什么事,比如浏览器请求这个url:localhost:8080/ssm/hello,包含了主机ip,端口,项目名,uri,而且这些数据最后会被封装到httpservletrequest中,在container中会拿出这些数据,进行查找具体的主机,哪个项目,项目中的servlet映射路径;无非是做这些事,不要想的太复杂

  从server中的标签来看,能看到几个标签engine,host,context,其实应该还有一个wrapper,这个wrapper是用来包装真正的servlet的,便于扩展,后面会说到的;

  

  上图就是一个container,一层包装一层,engine>>>host>>>context>>>wrapper;其中一个container中的engine只能配置一个,host可以配置多个,context可以配置多个;

  我们可以看作:一个最大的容器container,里面有个小一号的engine容器,里面还有一个更小一号的host容器,里面还有一个还小号的context容器,里面还有一个最小号的wrapper,而这个wrapper容器就是最小的容器了,这个容器有很多个,一个wrapper其实就是一个servlet,为了扩展方便才封装成wrapper!

  下面说说这些东西有什么作用;

  engine:看到名字应该就知道这是一个引擎,这是一个完整的servlet引擎,内部还包括了一些东西

  host:就是主机名,例如我们常见的localhost,由于可以配置多个,所以一个tomcat实例可以配置多域名,也是为了灵活使用吧!

  context:很多人都喜欢把这个叫做应用上下文,其实就是指的你的web应用;你想啊,你的web应用在tomcat运行的时候,是以context这个形式表现出来的,你就可以把这个context当作你的应用本身,比较类似的应该是:类加载到内存中是以class对象存在,应该差不多的道理吧!

  wrapper:可以有很多的wrapper容器,一个wrapper里面就是一个servlet,用几行粗略代码表示如下,可以很清楚的看到wrapper和servlet之间的关系 

 

  再说一下host和context的关系,请看下图tomcat8目录和webapps内部,这就应该说的很清楚了;

 

3.研究一下container的内部运行过程

  前面分析了container中的各个组成部分,无非是容器一层套一层,httpservletrequest请求穿过一层一层,最后就到达servlet中执行service方法,然后处理,再返回;

  就好像中学时候学的生物细胞结构一样,营养物质首先要穿过血管壁,再是细胞壁,细胞膜等等,就是一层一层的穿过,而且在穿过的途中会碰到很多关卡,会对这个营养物质做一些处理;(嘿嘿,生物的知识我也不知道说的对不对,瞎扯一下!)

   其实在这里httpservletrequest就如同一个营养物质,每经过一个容器都会被处理一下,在tomcat中就有这么一个叫做pipeline-value机制(就是管道-阀门机制)来处理;

  阀门其实类似一个过滤器filter;而且可以把每一层容器看作是一个管道,管道中有一个一个的阀门,最重要的就是每条管道的最后一个阀门(叫做基础阀,英语是basevalue),会调用下一条管道的第一个阀门,一直到wrapper的基础阀中会创建一个拦截器链filterchain,依次调用所以拦截器的dofilter方法以及servlet的service方法,再返回!在这个过程中,httpservletrequest每经过一个阀门,都会被处理一下(其中假如出现异常,那么就会取到异常信息包装成一个xxxresponse返回给客户端!)

  可以想象最后形状应该是一个奇奇怪怪的形状;于是我找了一幅图来看看

 

4.总结:

  这一节我们用图形来看了一下tomcat的基本结构和大概的运行过程,其实tomcat底层就是依赖socket来获得请求,然后进行封装,把请求放进一个容器中,经过一连串的管道-----阀门机制进行处理,最后到wrapper中会创建一个拦截器链,执行每一个拦截器的dofilter方法,然后再执行servlet的service方法,然后将结果返回客户端;

  用一幅图来看看这整个过程: 

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网