文章概览

  相信很多接触java的人都对Tom猫有着多少的熟悉,就个人而言,本来只知道Tom简单的操作与配置,就像裹上一层纱,迷迷糊糊的.

  Tomcat的书籍本来就不多,高分的还是很久之前的版本,直到最近看到下面这本书,解答了我的很多疑问,同时这篇文章将总结读书收获.

  如果觉得文章写的内容是你感兴趣的或者我的猫使你感兴趣,建议你读读这本书.

  

  该文会介绍Tom的架构,包括

  服务器如何从一层层抽象设计到完整的架构,

  Tom重要的几个组件(链接器,总处理引擎Catalina,jsp处理引擎Jsper),

  Tom的详细配置(conf目录文件,集群,调优)

Tomcat介绍

  Tom是一款全世界著名的轻量级应用服务器,基于java,服务于java.主要作为应用服务器来处理客户端发来的动态资源响应.

  目前版本是9.x,很多人都在使用6.x,但新版其实提供了很多新的功能,比如WebSocket的支持,点击了解WebSocket.

    

  Tomcat启动参数

    windows修改$CATALINA_HOME/bin/catalina.bat文件

    Set JAVA_OPTS=-server -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m

    linux修改$CATALINA_HOME/bin/catalina.sh文件

    JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m"

    -server  Server端启动Tomcat,Client启动Tomcat两者的初始化参数会有所不同

    -Xms1024m 初始化堆内存大小

    -Xmx2048m 允许的最大堆内存大小

    -XX:PermSize=256m 初始化非堆内存大小

    -XX:MaxPermSize=512m 允许的最大非堆内存大小

  Debug方式

    依赖于JDK提供的JPDA(Java Platform Debugger Architecture,Java平台调试体系)

    catalina jpda start

  目录结构

    

    该文使用的版本是apache-tomcat-9.0.1,目录大致都很容易理解.

    conf放置的Tomcat的核心配置文件,下文会介绍.

    webapps是默认的web app的应用目录,只要把项目目录放置进去就可以运行

    work是Tomcat运行时产生的jsp编译文件所存放的位置

总体架构

  Tomcat是一款应用服务器,我们从最根本的类一层一层演变,直至Tomcat当前版本.

1.应用服务器是接收其他计算机(客户端)发来的请求数据并对其解析,完成相关业务处理,然后把处理结果作为响应返回给计算机.

  

2.一个问题摆在眼前,前面Server请求监听和请求处理放在一起,应用服务器通常会与web服务器进行集群部署和负载均衡,但是这两者的协议并不是HTTP.

也就是说,服务器连接的另一端需要适配不同的协议来对请求作出不同的处理.前面的模型扩展性太差,应该分离请求监听和请求处理.

Connector模块管理请求监听,Container模块负责请求处理,两个组件都拥有start()和stop()来加载和释放自己维护的资源.

这样子,Server下可以有多个Connector来传送请求至不同的Container中.

3.上面的设计有个缺陷,既然server可以有多个Connector和Container,那么如何知道哪个Connector将请求发至哪个Container呢?

考虑一下下面这个设计图,

4.我们接触过的Tomcat应该是放置web app的容器,在哪放置web app?这将决定哪个app来处理Engine所获取的请求信息.

再想一下,我们浏览器是个app,对吧?然后服务器其实也是app对吧?网络就是两者的通信.我们来看一下网络是怎么进行通信的.

没错,web app需要端点信息(IP地址,端口号),我们需要提供这一层的抽象.一个Host下可以对应有多个app(Context).

5.现在设计已经可以满足两个应用的连接了,现在设想一下,应用该怎么进行表示?毕竟Tomcat作为一款Servlet容器而存在.首先Apache组织按照Servlet官方的标准,加入了Servlet的包装类Wrapper.

6.就目前为止,我们使用"容器"这一概念来形容处理接收客户端的请求并且返回响应数据的组件,依此,使用一个类Container来统一表示这一想法,让Engine,Host,Context,Wrapper这类组件来继承Container.

Container类能够添加子组件addChild方法,有时需要执行一些异步处理,所以加入backgroundProcess方法.

由于Engine,Host,Context,Wrapper这类的引用变成了父类Container,所以之前的强组合关系变成了弱组合关系.强弱关系指的是两个类直接关联或者是间接关联.

7.为了从抽象和复用层面上再审视一下当前设计,使概念更加清晰,提供通用性定义.由于所有容器都有着自身的生命周期管理方法,那么我们可以将其进行抽象成一个接口Lifecycle,在方法定义上加入初始化方法init,销毁方法destroy,事件监听方法addLifecycleListener和removeLifecycleListener.

8.上面这个设计Container部分具有伸缩性和扩展性,这很棒.接下来Tomcat的开发人员为了提高每个组件的灵活性,使其更易扩展,加入了Pipeline和Valve这两个接口.这两个接口的设计运用了职责链模式.

简单介绍以下职责链模式,关于设计模式可以查看博客里的文章《软件设计 : 聚焦设计模式》

职责链模式使用一个抽象类来统一定义处理器,然后将处理器构造成一条链,当Client端发来请求时,第一个Handler判断是否处理,不处理则往下个Handler传递,直至被处理或则处理链结束.

回头看Tomcat怎么运用这个设计模式,Pipeline接口用于构建职责链,Valve接口代表职责链上的每个处理器.

Pipeline中维护一个基础的Valve,它始终位于Pipeline执行链的末端,封装了具体的请求处理和输出响应过程.

这样就可以构造一条职责链,可是为什么要这么做?记得之前Container不就是可以自包含的容器吗?为什么要弄出多两个接口?

的确,Container可以自包含,但是它是作为容器抽象类而存在,而阀(Valve)作为接口而存在,我们可以在实现这个接口的类中添加属于我们自己的Valve实现类,你想做什么都行.

  就像水管一样,你如果是超级马里奥,你可以随时给它加个阀,做任何事.

9.前面的设计基本落在Container部分,来看看Connector的设计方案,Connector必须完成下面的功能项.

  ①监听服务器端口,读取客户端的请求

  ②将请求数据按指定协议进行解析

  ③根据请求地址匹配正确的容器进行处理

  ④将请求返回客户端

Tomcat支持多协议(HTTP/AJP)和多种IO方式(BIO,NIO,NIO2,APR,HTTP/2)

  

ProtocolHandler表示协议处理器,针对不同的协议和IO方式,提供不同的实现,ProtocolHandler包含一个Endpoint用来启动socket监听,该接口按照IO方式进行分类实现,还包含一个Process用于按照指定协议读取数据,并交由容器处理.

处理逻辑如下:

1.在Connector启动时,Endpoint会启动线程来监听服务器端口,并在接收到请求后调用Process进行数据读取.

2.当Process读取客户端请求之后,需要按照地址映射到具体的容器进行处理,即请求映射.

3.由于Tomcat各个组件采用通用的生命周期进行管理,而且通过管理工具进行状态变更,因此请求映射除了考虑映射规则的实现外,还要考虑容器组件的注册和销毁.

Tomcat采用Mapper来维护容器映射信息,按照映射规则(Servlet规范定义)查找容器;

MapperListener实现LifecycleListener和ContainerListener,用于在容器组件状态变更时,注册或者取消对应的容器映射信息;

MapperListener实现了Lifecycle接口,当Service启动时,会自动作为监听器注册到各个容器组件之上,同时将已创建的容器注册到Mapper;

Tomcat通过适配器模式实现了Connector与Mapper,Container的解耦,默认实现为CoyotoAdapter;

10.到这里,服务器可以正常接入请求和完成响应,可是我们还没考虑到一个关键的问题——并发

Tomcat使用组件式的设计理念,那么也会有并发组件.

Tomcat组织为此提供了一个Executor接口表示一个可以在组件间共享的线程池,该接口同样继承自Lifecycle接口,按照通用组件进行管理.

Executor由Service进行维护,因此同一个Service中的组件共享一个线程池.值得注意的是如果没有定义线程池,相关组件会自动创建线程池,此时线程池不再共享.

在Tomcat中,Endpoint会启动一组线程来监听Socket端口,当接收到客户请求会创建请求处理对象,并交由线程池处理,由此支持并发处理客户端请求.

11.现在Tomcat基础的核心组件已经完整了,但是架构其实还有很多组件没有显示出来.Tomcat开发人员为了让使用者很好地使用Tomcat,提供了一套配置环境来支持系统的可配置性——Catalina.

Catalina代表了整个Servlet容器架构,包含了上面所有组件,还有还没谈及的安全,会话,集群,部署,管理等Servlet容器组件.它通过松耦合的方式集成了Coyoto,以完成按照请求协议进行数据读写.同时,还包括启动入口、Shell程序等.

Bootstrap是Catalina的启动入口.

为什么Tomcat不通过Catalina启动,而又提供了Bootstrap?

查看一下Tomcat发布包目录,Bootstrap并不存放于Catalina的lib目录下,而是置于bin目录中.Bootstrap通过反射调用Catalina实例,与Tomcat服务器完全松耦合,它可以直接依赖JRE运行并为Tomcat应用服务器创建共享类加载器,用于构建Catalina实例以及整个Tomcat服务器.

至此,Tomcat的基础核心组件介绍结束,我们回顾一下组件的概念

Server   表示整个Servlet容器,一个Tomcat运行环境只存在一个Server,可存在多个Service.

Service    表示链接器和处理器的集合,同一个Service下的链接器将请求传至该Service下的处理器

Connector 表示链接器,用于监听并转化Socket请求,支持不同协议与IO方式

Container  表示容器组件,能执行客户端请求并返回响应的组件

Engine    表示顶级容器,是获取目标容器的入口

Host   表示Servlet引擎中的虚拟机,提供Host之类的域名信息

Context  表示一个web app应用上下文环境

Wrapper 具体的Servlet包装类

Executor   组件间共享的线程池

Tomcat启动与请求响应

Tomcat类加载器

应用服务器通常会自行创建类加载器以实现更加灵活的控制,这是对规范的实现(Servlet规范要求每个Web应用都有独立的类加载器实例),也是架构层面的考虑.

书中p46对类加载器进行了详细说明

JVM默认提供了三个类加载器来进行类加载,Tomcat在加载器上进行扩展,用来加载应用自身的类.

Bootstrap  JVM提供,加载JVM运行的基础运行类,即位于%JAVA_HOME%/jre/lib目录下的核心类库

Extension    JVM提供,加载%JAVA_HOME%/jre/lib/ext目录下的扩展类库

System      JVM提供,加载CLASSPATH指定目录下或者-classpath运行参数指定的jar包

         Tomcat的Bootstrap类即由这个加载器载入

Common   以System为父类加载器,是Tomcat应用服务器顶层的公用类加载器,

         其路径common.loader,默认指向$Catalina_Home/lib目录.

Catalina     用于加载Tomcat应用服务器的类加载器,路径为server.loader,

         默认为空,此时Tomcat使用Common类加载器加载应用服务器.

Shared    所有Web应用的类加载器,路径为shared.loader,默认为空.

         此时使用Common类加载器作为Web应用的父加载器.

Web App   加载WEB-INF/classes目录下未压缩的Class和资源文件以及/WEB-INF/lib目录下的jar包.

        该类加载器对当前web应用可见,对其他web应用不可见.

服务器 : Apache Tomcat - 理解架构层次的更多相关文章

  1. 关于Apache/Tomcat/JBOSS/Neginx/lighttpd/Jetty等一些常见服务器的区别比较和理解

    先说Apache和Tomcat的区别: Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. ...

  2. 主流服务器apache,iis,tomcat,jboss,resion,weblogic,websphere的区别

    在互联网高速发展的今天,不同种类的网站大量涌现,每个人都在享受着网络服务带来的便利.而创建自己的个性化网站的门槛不断降低.从事网站架构,这种当年的绝对“”高科技“”绝活.也从it人员的专利“”沦落“” ...

  3. Windows下Apache+Tomcat+jsp+php的服务器整合配置经验总结

    对于Apache+Tomcat+jsp+php的整合,针对不同的Tomcat和apache的版本,稍微有些区别. 一.所需软件 (1)JDK: jdk-7u15-windows-x64.exejdk的 ...

  4. Apache服务器和tomcat服务器有什么区别(转)

    Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的Web服务器运行.Apache是Web服务器而Tomcat是Java应用服务器. A ...

  5. JAVA-安装apache tomcat服务器

    下载地址:http://tomcat.apache.org/ 选择需要下载的版本 下载windows service installer,找到文件双击进行安装 next i agree next ne ...

  6. Apache服务器和tomcat服务器有什么区别?

    Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的 Web服务器运行.Apache是Web服务器而Tomcat是Java应用服务器. ...

  7. 辨析各类web服务器:Apache/Tomcat/Jboss/Nginx/等,还有Nodejs

    先说一下各类服务器能干啥,特点是啥,然后在区分他们的类别. (1)Apache: Apache是指Apache软件基金会的Apache HTTP Server, 它能够接收http请求,然后返回各类资 ...

  8. Android 利用apache tomcat在自己的电脑上搭建服务器

    1.什么叫服务器 装了服务器端的软件的那台电脑被称为服务器.常见的服务器的软件有apache tomcat. 2.Tomcat 介绍 tomcat是一种轻量级的web容器服务器,使用tomcat可以实 ...

  9. 学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat

    学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat 2019-05-09   19:28:42 注:项目(MyEclipse)创建的时候选择:Web Service Pr ...

随机推荐

  1. The Moving Points hdu4717

    The Moving Points Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  2. 关于el-dialog,我更推荐的用法

    最近的项目里用上了vue和element-ui.vue这种轻量级渐进式框架的舒适自不必说,但一直困扰着我的,是如何方便又优雅的弹出模态dialog... 对于我这种在jquery出现之前就用docum ...

  3. Ionic3学习笔记(五)动画之使用 animate.css

    本文为原创文章,转载请标明出处 目录 前言 animate.css 的使用 animate.scss 的使用 1. 前言 animate.css 是一款强大的.跨浏览器的预设CSS3动画库,内置了很多 ...

  4. Android ListView getViewTypeCount 的返回值问题解决

    最近在学慕课网上的一个实战课程,期间有一个智能聊天机器人模块. 聊天界面通过 ListView 显示,用 Adapter 加载.一般来说,单对单的聊天,两者发出的话分别列在聊天页面的左右两边.所以,在 ...

  5. less使用ch1--简单使用

    1 ku.less .reset(){ *{margin:0;padding:0;} ul.ol{list-style: none;} a{text-decoration: none;} img{bo ...

  6. 【转】python time模块详解

    python 的内嵌time模板翻译及说明  一.简介 time模块提供各种操作时间的函数  说明:一般有两种表示时间的方式:       第一种是时间戳的方式(相对于1970.1.1 00:00:0 ...

  7. MVC中View界面数据呈现示例

    @using System.Text; @model List<MvcShopping.Models.ProductCategory> @{ ViewBag.Title = "测 ...

  8. windows下利用nginx 做IIS负载均衡

    如果网站流量变大,就想加服务器分担压力,当然就要用到负载均衡,在windows 2003有自带的网络负载均衡,但配置还是挺麻烦的虽然有轮训和iphash的效果,但效果不算好. nginx小巧,下载不到 ...

  9. JavaWeb基础之JdbcUtils工具类final

    JdbcUtils工具类3.0最终版,添加了事务相关功能和释放链接.最终版本可以直接打成jar包,在后面的基本项目都会使用该工具类 1. JdbcUtils代码 /** * 最终版 * @author ...

  10. ASP.NET MVC 学习笔记 1

    1. 什么是ASP.Net MVC ASP.Net MVC是一种开发Web应用程序的工具(is a web application development framework),采用Model-Vie ...