Tomcat架构(一)之总体架构

1.Server

我们可以将服务器描述为这样的应用:

    它接受客户端发送的的请求数据并进行解析,完成相关业务处理后,将处理结果作为响应返回给请求的客户端。

通常情况下我们使用Socket监听服务器指定的端口来实现该功能,因此一个简单的服务器设计如下:

我们通过start()方法启动服务器,打开socket监听服务器端口,接受客户端请求进行处理并返回响应。同时提供一个stop()方法来停止服务器并释放网络资源。

2.Connector和Container

很快我们就会发现,将请求监听和业务处理放在一起的扩展性很差。比如我们有多种不同协议(AJP和HTTP)的请求,但请求处理都是相同的时候。那么我们如何通过面向对象的方式来解决这个问题呢,自然就是将请求和处理从概念上分离。我们做了如下改进:

一个Server可以包含多个Connector(链接器)和Container(容器),其中Connector负责开启Socket并监听客户端的请求、返回响应数据;Container负责具体的请求处理。Connector和Container分别拥有自己的start()和stop()方法来加载和释放资源。

但这样设计有一个明显的缺陷,既然Server可以包含多个链接器和容器,那么如何知道来自某个Connector的请求分发给哪个Container处理呢?我们看以下一个更合理的方案:

一个Server包含多个Service(它们相互独立,只是共享一个JVM和系统类库),一个Service负责维护多个Connector和一个Container,这样来自链接器的请求只能由它所属的Service所维护的那个容器处理。

在Tomcat中,Container是一个更通用的概念,为了与tomcat组件命名一致,我们将container重新命名为Engine,以表示整个servlet引擎,修改后的设计如下:

3.Container设计

上面已经解决了网络协议和容器的解耦,但是应用服务器是用来部署并运行web应用的,它是一个运行环境,而不是业务处理系统。因此我们需要在Engine容器中支持管理web应用,当接收到connector的处理请求时,Engine容器要能找到一个合适的web应用进行处理。修改方案为:

我们使用Context来代表一个web应用,并且一个Engine容器可以包含多个Context.

这是不是一个合理的方案呢?如果一台主机承担了多个域名的服务,如www.baidu.com和mp.csdn.net,那么我们如何实现呢?当然你可以在该主机上运行多个服务器实例,但如果我们希望只运行一个服务器就实现呢?(服务器灵活部署方式的体现)

我们可以将每个域名视为一个虚拟主机,在每个虚拟主机上运行web应用,对于客户端来说,他并不知道服务端用几台主机为他服务,他只知道哪些域名能提供哪些服务,因此应用服务器将每个域名视为一个虚拟主机的方案是合理的,修改后的设计为:

我们用Host表示一个虚拟主机,一个Host可以包含多个Context.

 当然一个Engine既可以包含多个Host又可以包含多个Context.

在一个web应用中,可以包含多个servlet实例以处理来自不同链接的请求,在tomcat中,Servlet被定义为Warpper,因此设计为:

 

有仔细阅读的小伙伴都会发现,上面我们多次提到了“容器”的概念,其实容器的含义并不相同,有时候指Engine,有时候指Context,但是他代表了能处理客户端请求并响应数据的一类组件。

我们使用Container表示容器,Container可以添加并维护子容器,因此Engine、Context、Warpper均继承自Container:

Container还有一个很重要的功能就是后台处理,在很多情况下,Container需要执行一些异步处理,而且是定期执行,如每隔30秒执行一次。tomcat对web应用文件变更的扫描就是通过该机制实现的

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值