文章概览

  相信很多接触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. 17.tslib安装以及使用

    1.先在网上下载 tslib-1.4.tar.gz压缩包 2.然后在ubuntu编译: tar xzf tslib-1.4.tar.gz cd tslib ./autogen.sh mkdir tmp ...

  2. netsh用法

    netsh(Network Shell) 是一个windows系统本身提供的功能强大的网络配置命令行工具. 导出配置脚本:netsh -c interface ip dump > c:\inte ...

  3. 分页查询不知你是否真正的懂和PHP的正则的应用和一些性能优化

    一.不废话太多  直接进入例子. 1  问题: 有一张收藏表,里面存储的是用户和图书ID.数据量为1亿.现在要求分页获取所有用户ID(不重复),写下你的sql语句.   表结构大致如下:       ...

  4. 在sqlserver2005/2008中备份数据库,收缩日志文件

    ---1.先备份数据库(含日志文件) use myhis go backup database myhis to disk='d:\myhis_rzbak' go ---2.设为简单恢复模式 use ...

  5. NodeJS 初学之安装配置环境

    [TOC] 1.环境安装 操作系统: Ubuntu 16.04.2 LTS 1.1安装nvm ryan@ryan-900X5L:~/temp$ curl https://raw.githubuserc ...

  6. 使用WinDBG调试查看C#内存转储文件

    有时候我们想查看一个正在运行的程序内存中的数据,可以在任务管理器将内存状态保存为转储文件,并使用WinDBG验证,这里我们来试试: 0.安装WinDBG 1.首先写个代码用来测试 一个class pu ...

  7. win10 uwp 入门

    UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客. 关于UWP介绍可以参见:http://lib.csdn.net/article/csharp/32451 首先需要申请一 ...

  8. Python和SQL 2017的强大功能

    Python和SQL Server 2017的强大功能   原文来自:https://www.red-gate.com/simple-talk/sql/sql-development/power-py ...

  9. C语言第一次实验报告

    一.实验题目,设计思路,实现方法 7-7 计算火车运行时间(15 分) 4-5 求简单交错序列前N项和(15 分) 4-2-7 装睡(10 分) 思路:7-7须将时间统一单位,化为以分钟计算再将两者相 ...

  10. FastDFS 简介

    FastDFS开源的分布式文件系统,功能包括:文件存储,文件同步,文件访问(文件上传,文件下载等),解决了大容量存储和负载均衡的问题,特别适合以文件为载体的在线服务,如服务网站,视频网站等 FastD ...