Tomcat 架构 (一)
在实践过程中,从WebSphere中实现一个EJB的容器以及从WebLogic中实现一个JMS几乎都是不可能的,然而来自Apache基金会的servlet容器Tomcat至少在理论上是可能做到的。
请注意,这里所说的“接口”也包含抽象类。规范的API可能会提供一个实现的模板,其中包括定义了一些抽象的基本类型的操作来供服务提供者去实现。
而服务提供者应提供这些接口和抽象类的具体实现。例如,在Tomcat中HttpSession接口被以org.apache.catalina.session.StandardSession的形式实现。
下面让我们来看看Tomcat容器的整体结构:
本文的目的是覆盖这张图中所涉及的主要请求处理组件。而上图中的一些高级主题如集群和安全则不是在本文讨论的范围之内。
本图中,Service, Host, Context以及Wrapper实例之后的符号“+”表示这些对象能存在一个或多个。例如一个Service可能只有一个Engine,但是一个Engine可以包含一个或多个Host;另外,图中旋转的圆圈代表请求处理器的线程池。
1、组件分类
Tomcat架构采用类似俄罗斯嵌套娃娃(译注:一层套一层)的设计方式。换句话说,就是一个容器包含另一个容器,而这个被包含的容器实体反过来再包含别的实体。
而在Tomcat中,“容器”是对任何包含有其他组件的组件的通称,如Server、Service、Engine、Host以及Context都称为容器。 其中Server和Service组件比较特殊些,被设计为顶级元素,代表Tomcat运行实例。而Tomcat其他所有的组件都属于这些顶级元素。其中Engine、Host以及Contex都被官方称为容器并依赖处理传入请求和生成适当数据响应的相关组件。
而被嵌套的组件可以作为子元素来嵌入顶级元素或其他容器之中来配置这些组件的工作方式。这其中,嵌套组件包括代表可重用的工作单元的Valve组件、代表Valve链的Pipeline组件以及帮助特定容器建立容器管理安全的Realm组件。
此外,嵌套组件中还包括用来强制servlet中的类使用指定的规范来加载类的加载器;为每个web应用提供session管理的管理器;代表web应用中静态资源以及提供机制来访问这些资源的资源管理组件;以及在容器的生命周期内允许在重要的点插入自定义处理程序的监听器组件,例如当某个组件启动或停止时就可以使用监听器。
值得注意的是,并不是所有的前台组件都可以被嵌套在每个容器中。
这里还有最后一个主要组件,那就是连接器(Connector);它代表一个连接点,通过这个连接点外部客户端可以(比如网页浏览器)可以连接至Tomcat容器。
在我们去学习这些组件之前,让我们快速看下这些组件的大体结构:
请注意,上图只展示了每个容器的关键属性。
启动Tomcat时,它运行的Java虚拟机(JVM)实例中包含一个服务器顶级元素,该元素代表了一个完整Tomcat服务器。一个Tomcat服务器通常只包含一个Service对象,这个对象是一种包含一个或多个连接器(Connector,如HTTP、HTTPS连接器)的结构化元素,正是这些Connector通过一个Catalina的Servlet引擎来处理传入的请求。
引擎(Engine)表示Tomcat中处理请求的核心代码,并且它还支持在其下定义多个虚拟主机(Host)。虚拟主机允许Tomcat引擎在将配置在一台机器上的多个域名(如www.my-site.com、www.your-site.com)分割开来互不干扰。
反过来,每个虚拟主机又可以支持多个web应用部署在它下边,这就是我们所熟知的上下文对象(Context)。上下文(Context)是使用由Servlet规范中指定的Web应用程序格式表示,不论是压缩过的war包形式的文件还是未压缩的目录形式。此外,上下文一般是在web.xml文件中配置,并且该配置是根据servlet规范定义的。
从上下问角度看,在上下文中又可以部署多个servlet,并且每个servlet都会被一个包装组件所包含。
至此,我们以上所说的Server、Service、Connector、Engine、Host、Context元素都会通过server.xml配置文件在tomcat实例中被使用。
2、架构的好处
这种架构有一些很实用的功能。它不仅便于组件的生命周期管理(每个组件管理生命周期并通知其子节点),而且便于在Tcomat启动时根据从配置文件中读取的配置文件来动态组装出Tomcat服务器实例。尤其是server.xml在启动时就会被解析,其内容正是用来实例化和配置被定义的元素,并随后组装到正在运行的Tomcat实例中。
server.xml文件只会被读取一次,对server.xml的修改只有在Tomcat重启后才会起作用。
同时这种架构简化配置,允许子容器继承父容器的配置。例如Realm定义了一个可验证权限的数据存储,并且可以授权用户通过web应用来访问受保护资源。为了便于配置,针对引擎定义的Realm适用于它所有的host和context配置。同时,某一个特定的子元素如context也可以通过继承父类的realm来实现自定义realm。
3、顶级组件
Server和Service容器组件存在的目的是尽可能的方便结构化。Server表示正在运行的Tomcat实例,可包含一个或多个Service子容器;其中每个Service代表一组请求处理组件。
Server
Server代表完整的Tomcat实例在Java虚拟集中是单例,主要是用来管理容器下各个Serivce组件的生命周期。
下图描述了Server组件的关键方面。如图所示,Server实例是通过server.xml配置文件来配置的;其根元素<Server>所代表的正是Tomcat实例,默认实现为org.apache.catalina.core.StandardServer。但是,你也可以通过<Server>标签的class属性来自定义服务器实现。
服务器可重要的一方面就是它打开了8005端口(默认端口)来监听关闭服务命令(默认情况下命令为SHUTDOWN)。当收到shutdown命令后,服务器会优雅的关闭自己。同时出于安全考虑,发起关闭请求的连接必须来自同一台机器上的同一个运行中的Tomcat实例。
此外,Server还提供了一个Java命名服务和JNDI服务,可以通过这两个服务可以使用名称来注册专用对象(如数据源配置)。在运行期,单个组件(如Servlet)可以使用对象名称来通过服务器的JNDI绑定服务来查找需要的对象相关信息。
虽然JNDI实现并不是Servlet容器的功能,但是它属于JavaEE规范一部分,并且可以为Servlet从应用服务器或者servlet容器中获取所需要的信息提供服务。
虽然在一个JVM中通常只有一个服务器实例,但是完全可以在同一台物理机器中运行多个服务器实例,每个实例对应一个JVM实例;这种做法将运行在一个JVM中的应用中的错误与其他JVM中应用的错误隔离开来互不影响,这也简化了维护使得JVM的重启与其他独立开来。这是一个共享主机环境的机制(另一种是虚拟主机机制,很快我们将会看到),这种机制下需要将运行在同一物理主机下的多个web应用隔离开来。
Service
Server代表Tomcat实例本身,Service则代表Tomcat中一组请求处理的组件。
Server可以包含一个或多个Service,但每个Service则将一组Connector组件和Engine关联了起来。
客户端请求首先到达连接器(connector),连接器在再将这些请求轮流传入引擎中处理,而Engine也是Tomcat中请求处理的关键组件。上图中展示了HTTP连接器、HTTPS连接以及AJP组件。
一般很少会修改这个元素,而且默认的Service实例通常就足够使用了。
值得注意的是上图中可能有多个Service实例。如图所示,一个Service集中了一些连接器,每个连接器监控一个指定的IP及端口并通过指定的协议做出响应。所以,一个关于多个服务的使用示例就是当你希望通过IP地址或者端口号来区分不同服务(包括这些服务中所包含的engine、host、web应用)时。
例如,当需要配置防火墙来为用户开放某一个服务而该主机上托管的其他服务仍然只是对内部用户可见,这将确保外部用户无法访问内部应用程序,因为对应访问会被防火墙拦截。
因此,Service仅仅是一个分组结构,它并不包含任何其他的附加功能。
4、连接器(Connector)
Connector是客户端连接到Tomcat容器的服务点它为引擎提供协议服务来将引擎与客户端各种协议隔离开来,如HTTP、HTTPS、AJP协议。
Tomcat有两种可配的工作模式--独立模式或在同一web服务器中共享模式。
在独立模式下,Tomcat会配置HTTP和HTTPS连接器,这可以使Tomcat看起来更像完整的web服务器以处理静态请求内容同时还委托Catalina引擎来处理动态内容。
发布时,Tomcat为这种运作模式提供了3种可能实现,即HTTP、HTTP1.1以及HTTPS。
Tomcat中最常见的连接器为标准连接器,也就是通过java标准I/O实现的Coyote连接器。
你也许希望使用一些技术实现,这其中就包括使用Java1.4中引入的非阻塞特性NIO,另一方面可能是通过APR充分利用本地代码来优化特定的操作系统。
值得注意的是,Connector和Engine不仅运行在同一个JVM中,而且还运行在同一个Tomcat服务实例中。
在共享模式中,Tomcat扮演着对web服务器如Apache httpd和微软的IIS支撑的角色。这里web服务器充当客户端通过Apache模块或者通过dll格式ISAPI模块来和Tomcat通信。当该模块判定一个请求需要传入Tomcat处理时,它将使用AJP协议来与Tomcat通信,该协议为二进制协议,在web服务器和Tomcat通信时比基于文本的Http协议更高效。
在Tomcat端,通过AJP连接器来接收wen服务器的请求,并将请求解释为Catalina引擎可处理的格式。
这种模式下Tomcat作为来自web服务器的单独进程运行在自身独立的JVM中。
不论在哪种模式中,Connector的基本属性都是它所需要监听的IP地址及端口号,以及所支持的协议。还有一个关键属性就是并发处理传入请求的最大线程数。一旦所有的处理线程都忙,那么传入的请求都将被忽略,直到有线程空闲为止。
默认情况下,连接器会监听指定物理机器上的所有IP(address属性默认值为0.0.0.0);但也可以配置为只监听某一个IP,这将限制它只接收指定ip的连接请求。
任意一个连接器接收到的请求都会被传入单一的服务引擎中,而这个引擎,就是众所周知的catalina,它负责处理请求并生成响应结果。
引擎将生成的结果返回给连接器,连接器再通过指定的协议将结果回传至客户端。
未完待续......
Tomcat 架构 (一)的更多相关文章
- tomcat架构分析 (Session管理)
Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是获取一个session,然后向session中存取数据,然后再销毁session.那么如何产生se ...
- tomcat架构
很多开源应用服务器都是集成tomcat作为web container的,而且对于tomcat的servlet container这部分代码很少改动.这样,这些应用服务器的性能基本上就取决于Tomcat ...
- Tomcat架构(四)
8标准覆盖机制J2SE 1.4 and 1.5 都包含了一个XML处理解析器的Java API .Bootstrap 类加载器加载这个解析器的类文件,所以这个解析器会优先于任何一个安装在CLASSPA ...
- tomcat架构分析-索引
出处:http://gearever.iteye.com tomcat架构分析 (概览) tomcat架构分析 (容器类) tomcat架构分析 (valve机制) tomcat架构分析 (valve ...
- Tomcat架构以及理解sever.xml
Tomcat架构图 当用户在地址栏输入访问地址后,首先识别访问协议(假设为http),那么通过针对于http协议传输的Connector连接器,连接到tomcat的服务中,连接后开始检测Engine下 ...
- (转)tomcat架构&session共享
(二期)16.tomcat的整体架构与session共享方案 [课程16]tomcat...共享.xmind47.6KB [课程16]tomcat...流程.xmind0.6MB [课程16]tomc ...
- Tomcat架构解析(一)-----Tomcat总体架构
Tomcat是非常常用的应用服务器,了解Tomcat的总体架构以及实现细节,对于理解整个java web也是有非常大的帮助. 一.Server 1.最简单的服务器结构 最简单的服务器结构如图所示: ...
- tomcat架构分析(概览)
出处:http://gearever.iteye.com Tomcat是目前应用比较多的servlet容器.关于tomcat本身的特点及介绍,网上已经有很多描述了,这里不再赘述.Tomcat除了能够支 ...
- tomcat架构分析(connector BIO 实现)
出处:http://gearever.iteye.com 在tomcat架构分析(概览)中已经介绍过,connector组件是service容器中的一部分.它主要是接收,解析http请求,然后调用本s ...
随机推荐
- [D3] 8. Margins
If you want ot add margins, should append graphics container in svg var svg = d3.select('#chartArea' ...
- Swift 析构器deinit
析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标识,类似于构造器用init来标识. 原理: Swift会自动释放不再需要的实例以释放资源.Swift通 ...
- oracle用户管理实例
oracle中的用户角色分为预定义角色和自定义角色. 角色是把常用的权限集中起来形成角色. 授权/分配角色命令 grant 权限/角色 to 用户 收回权限命令: revoke 综合案例: 创建一个用 ...
- Java基础知识强化之集合框架笔记60:Map集合之TreeMap(TreeMap<Student,String>)的案例
1. TreeMap(TreeMap<Student,String>)的案例 2. 案例代码: (1)Student.java: package cn.itcast_04; public ...
- 2014年最新720多套Android源码2.0GB免费一次性打包下载
之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...
- Xcode4快速Doxygen文档注释 — 简明图文教程
转自:http://blog.csdn.net/totogo2010/article/details/9100767 准备2个文件: 文件一,ThisService.app 文件二,Doxygen.r ...
- Bash中的数组
变量:$VAR或者${VAR} 数组:${VAR[$i]} 打印整个数组:echo ${VAR[@]} 统计数组元素个数:echo ${#VAR[@]} 从文件读入数组(按行读入):VAR=(`cat ...
- Maven浅析-2 什么是Maven
1.简单点讲:Maven就是一个项目构建工具.它可以生成一个artifact(component),还可以帮我们管理项目依赖(如附加的组件Filters等). 2.从整体讲:Maven也可以看作一个项 ...
- HTML5的你应该记住的一些知识点
刚开始学HTML5是从w3school开始的,那只是非常简单的一些了解,后面开始看一些xiongdilian的HTML5+CSS3的视频,照着视频做了一些简单的demo(需要的童鞋可以联系我,当然网上 ...
- [Mime] MimeEntity--MimeEntity Mime实体帮助类 (转载)
点击下载 MimeEntity.rar 这个类是关于Mime实体的类看下面代码吧 /// <summary> /// 类说明:Assistant /// 编 码 人:苏飞 /// 联系方式 ...