Tomcat系统架构

1、顶层架构

最顶层的容器是server,代表整个服务器,一个server可以包含至少一个service,用于提供具体服务。 

Service主要包含两个部分:Connector和Container。Tomcat的心脏就是这两个组件,作用如下:1、Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转换;2、Container用于封装和管理Servlet,以及具体处理Request请求。

一个Tomcat只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但可以有多个Connector。这是因为一个服务可以有多个连接,如同时提供Http和Https连接。也可以提供相同协议不同端口的连接。

多个 Connector 和一个 Container 就形成了一个 Service,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了!所以整个 Tomcat 的生命周期由 Server 控制。

上述的包含关系,都可以在conf目录下的server.xml配置文件里看出。

Server标签设置的端口号为8005,shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。一个Server有一个Service,当然还可以进行配置,一个Service有多个,Service左边的内容都属于Container的,Service下边是Connector。 

2、Tomcat顶层架构小结

(1)Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container; 
(2) Server掌管着整个Tomcat的生死大权; 
(4)Service 是对外提供服务的; 
(5)Connector用于接受请求并将请求封装成Request和Response来具体处理; 
(6)Container用于封装和管理Servlet,以及具体处理request请求;

3、Container架构

Container用于封装和管理Servlet,以及具体处理Request请求,在Connector内部包含了4个子容器

4个子容器的作用分别是:

(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine; (2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点; (3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件; (4)Wrapper:每一Wrapper封装着一个Servlet;

Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。

我们访问应用Context的时候,如果是ROOT下的则直接使用域名就可以访问,例如:www.ledouit.com,如果是Host(webapps)下的其他应用,则可以使用www.ledouit.com/docs进行访问,当然默认指定的根应用(ROOT)是可以进行设定的,只不过Host站点下默认的主营用是ROOT目录下的。

4、Context

<Context docBase="ROOT11" path="/han" reloadable="true" />在Host标签里。

path:指定访问该web应用的URL入口

docBase:指定访问该WEB应用的文件路径,可以绝对路径,也可以给appBase的相对路径

reloadable:true-如果class文件改动,会自动重新加载web应用

5、webapps

一般将web应用打包成war包格式,然后拷贝到tomcat的webapps目录下进行发布,tomcat、将自动解压war包并生成对应的目录,在内存中动态创建context路径。在正式部署时按照4修改路径!

=====================================================================

Tomcat和Catalina是什么关系?

Tomcat的前身为Catalina,Catalina又是一个轻量级的Servlet容器

Tomcat的前身为Catalina,Catalina又是一个轻量级的Servlet容器。在美国,catalina是一个很美的小岛。所以Tomcat作者的寓意可能是想把Tomcat设计成一个优雅美丽且轻量级的web服务器。Tomcat从4.x版本开始除了作为支持Servlet的容器外,额外加入了很多的功能,比如:jsp、el、naming等等,所以说Tomcat不仅仅是Catalina

# 什么是Servlet?

所谓Servlet,其实就是Sun为了让Java能实现动态可交互的网页,从而进入Web编程领域而制定的一套标准!

在互联网兴起之初,当时的Sun公司(后面被Oracle收购)已然看到了这次机遇,于是设计出了Applet来对Web应用的支持。不过事实却并不是预期那么得好,Sun悲催地发现Applet并没有给业界带来多大的影响。经过反思,Sun就想既然机遇出现了,市场前景也非常不错,总不能白白放弃了呀,怎么办呢?于是又投入精力去搞一套规范出来,这时Servlet诞生了!

一个Servlet主要做下面三件事情:

  • 创建并填充Request对象,包括:URI、参数、method、请求头信息、请求体信息等
  • 创建Response对象
  • 执行业务逻辑,将结果通过Response的输出流输出到客户端

Servlet没有main方法,所以,如果要执行,则需要在一个容器里面才能执行,这个容器就是为了支持Servlet的功能而存在,Tomcat其实就是一个Servlet容器的实现

# Tomcat 总结架构

下图应该是网上能找的最好的关于Tomcat的架构图了, 我们来看下它的构成:

从组件的角度看

  • Server: 表示服务器,它提供了一种优雅的方式来启动和停止整个系统,不必单独启停连接器和容器;它是Tomcat构成的顶级构成元素,所有一切均包含在Server中;

  • Service: 表示服务,Server可以运行多个服务。比如一个Tomcat里面可运行订单服务、支付服务、用户服务等等;Server的实现类StandardServer可以包含一个到多个Services, Service的实现类为StandardService调用了容器(Container)接口,其实是调用了Servlet Engine(引擎),而且StandardService类中也指明了该Service归属的Server;

  • Container: 表示容器,可以看做Servlet容器;引擎(Engine)、主机(Host)、上下文(Context)和Wraper均继承自Container接口,所以它们都是容器。

    • Engine -- 引擎
    • Host -- 主机
    • Context -- 上下文
    • Wrapper -- 包装器
  • Connector: 表示连接器, 它将Service和Container连接起来,首先它需要注册到一个Service,它的作用就是把来自客户端的请求转发到Container(容器),这就是它为什么称作连接器, 它支持的协议如下:

    • 支持AJP协议
    • 支持Http协议
    • 支持Https协议
  • Service内部还有各种支撑组件,下面简单罗列一下这些组件

    • Manager -- 管理器,用于管理会话Session
    • Logger -- 日志器,用于管理日志
    • Loader -- 加载器,和类加载有关,只会开放给Context所使用
    • Pipeline -- 管道组件,配合Valve实现过滤器功能
    • Valve -- 阀门组件,配合Pipeline实现过滤器功能
    • Realm -- 认证授权组件

# 从web.xml配置和模块对应角度

上述模块的理解不是孤立的,它直接映射为Tomcat的web.xml配置,让我们联系起来看

# 从一个完整请求的角度来看

通过一个完整的HTTP请求,我们还需要把它贯穿起来

假设来自客户的请求为:http://localhost:8080/test/index.jsp 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector,然后

  • Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应
  • Engine获得请求localhost:8080/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源代码分成5个子模块,分别是:

  • Jsper模: 这个子模块负责jsp页面的解析、jsp属性的验证,同时也负责将jsp页面动态转换为java代码并编译成class文件。在Tomcat源代码中,凡是属于org.apache.jasper包及其子包中的源代码都属于这个子模块;

  • Servlet和Jsp模块: 这个子模块的源代码属于javax.servlet包及其子包,如我们非常熟悉的javax.servlet.Servlet接口、javax.servet.http.HttpServlet类及javax.servlet.jsp.HttpJspPage就位于这个子模块中;

  • Catalina模块: 这个子模块包含了所有以org.apache.catalina开头的java源代码。该子模块的任务是规范了Tomcat的总体架构,定义了Server、Service、Host、Connector、Context、Session及Cluster等关键组件及这些组件的实现,这个子模块大量运用了Composite设计模式。同时也规范了Catalina的启动及停止等事件的执行流程。从代码阅读的角度看,这个子模块应该是我们阅读和学习的重点。

  • Connector模块: 如果说上面三个子模块实现了Tomcat应用服务器的话,那么这个子模块就是Web服务器的实现。所谓连接器(Connector)就是一个连接客户和应用服务器的桥梁,它接收用户的请求,并把用户请求包装成标准的Http请求(包含协议名称,请求头Head,请求方法是Get还是Post等等)。同时,这个子模块还按照标准的Http协议,负责给客户端发送响应页面,比如在请求页面未发现时,connector就会给客户端浏览器发送标准的Http 404错误响应页面。

  • Resource模块: 这个子模块包含一些资源文件,如Server.xml及Web.xml配置文件。严格说来,这个子模块不包含java源代码,但是它还是Tomcat编译运行所必需的。


参考资料:Tomcat - 理解Tomcat架构设计 | Java 全栈知识体系 (pdai.tech)

2023-02-23

1、<welcome-file-list>标签

可以设置多个首页<welcome-file>,容器启动后会在根目录下依次查找匹配的物理存在的文件,返回第一个找到的文件,没有找到报404错误。

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index1.jsp</welcome-file>   
    </welcome-file-list>

默认是用的conf目录下的,但是webapps/ROOT/里的<welcome-file-list>会覆盖conf目录下的。

2、Tomcat部署的三种方式

2.1、在部署目录webapps部署war包

<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

 ...

</Host>

  • unpackWARs参数表示,tomcat会对部署在webapps目录中的war文件自动解压,如果为false,则不执行自定解压,但会影响程序的运行效率,
  • autoDeploy表示自动部署,即热部署

这种方式也可以直接部署文件夹,但要求部署的文件夹要符合web目录的标准 

2.2、在server.xml加入context标签

这种方式需要修改server.xml,不建议使用

2.3、独立的部署文件

首先来到\conf\Catalina目录,

再依据虚拟服务器名称一致的方式,创建一个目录(如:localhost),

建一个xml文件,完成项目部署,文件名与部署项目的上下文名称对应,例如:webdemo.xml

3、Webapps目录下的ROOT目录

tomcat的默认工程目录,用ip:port访问。其他目录访问路径需要加上 /目录名称!

4、conf/context.xml文件

<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
</Context>

监控资源文件,如果conf/web.xml或者应用下的 WEB-INF/web.xml改变了,会自动加载改变。

5、${catalina.base} 

是在catalina.bat启动文件里设置的环境参数值

6、源码走读

BootStrap.load()

Catalina. load()-解析server.xml文件,放入字段对象

StandardServer.initInternal()

service可能有多个,所以循环调用StandardService.initInternal()

StandardEngine.init(),new了一个startStopExecutor,据说是host、context、wrapper的启动线程池,应该是在start里面调线程池启动

如果server.xml有线程池配置,调用StandardThreadExecutor.init()

Connector可能多个,所以循环调用Connector.init()

new一个CoyoteAdapter,

AbstractHttp11Protocol.init()

NioEndPoint.bind()-serverSock.socket().bind(addr,getAcceptCount();

poller线程池大小:pollerThreadCount =Math.min(2,Runtime.getRuntime().availableProcessors())

7、Pipeline管道   List<Valve>阀门

貌似日志就是阀门做的?

StandardWrapperValve里面调servlet

filterChain

Tomcat没有解析请求体,直接用request.getInputstream

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值