服务器 : Apache Tomcat - 理解架构层次
文章概览
相信很多接触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 - 理解架构层次的更多相关文章
- 关于Apache/Tomcat/JBOSS/Neginx/lighttpd/Jetty等一些常见服务器的区别比较和理解
先说Apache和Tomcat的区别: Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. ...
- 主流服务器apache,iis,tomcat,jboss,resion,weblogic,websphere的区别
在互联网高速发展的今天,不同种类的网站大量涌现,每个人都在享受着网络服务带来的便利.而创建自己的个性化网站的门槛不断降低.从事网站架构,这种当年的绝对“”高科技“”绝活.也从it人员的专利“”沦落“” ...
- Windows下Apache+Tomcat+jsp+php的服务器整合配置经验总结
对于Apache+Tomcat+jsp+php的整合,针对不同的Tomcat和apache的版本,稍微有些区别. 一.所需软件 (1)JDK: jdk-7u15-windows-x64.exejdk的 ...
- Apache服务器和tomcat服务器有什么区别(转)
Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的Web服务器运行.Apache是Web服务器而Tomcat是Java应用服务器. A ...
- JAVA-安装apache tomcat服务器
下载地址:http://tomcat.apache.org/ 选择需要下载的版本 下载windows service installer,找到文件双击进行安装 next i agree next ne ...
- Apache服务器和tomcat服务器有什么区别?
Apache与Tomcat都是Apache开源组织开发的用于处理HTTP服务的项目,两者都是免费的,都可以做为独立的 Web服务器运行.Apache是Web服务器而Tomcat是Java应用服务器. ...
- 辨析各类web服务器:Apache/Tomcat/Jboss/Nginx/等,还有Nodejs
先说一下各类服务器能干啥,特点是啥,然后在区分他们的类别. (1)Apache: Apache是指Apache软件基金会的Apache HTTP Server, 它能够接收http请求,然后返回各类资 ...
- Android 利用apache tomcat在自己的电脑上搭建服务器
1.什么叫服务器 装了服务器端的软件的那台电脑被称为服务器.常见的服务器的软件有apache tomcat. 2.Tomcat 介绍 tomcat是一种轻量级的web容器服务器,使用tomcat可以实 ...
- 学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat
学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat 2019-05-09 19:28:42 注:项目(MyEclipse)创建的时候选择:Web Service Pr ...
随机推荐
- 17.tslib安装以及使用
1.先在网上下载 tslib-1.4.tar.gz压缩包 2.然后在ubuntu编译: tar xzf tslib-1.4.tar.gz cd tslib ./autogen.sh mkdir tmp ...
- netsh用法
netsh(Network Shell) 是一个windows系统本身提供的功能强大的网络配置命令行工具. 导出配置脚本:netsh -c interface ip dump > c:\inte ...
- 分页查询不知你是否真正的懂和PHP的正则的应用和一些性能优化
一.不废话太多 直接进入例子. 1 问题: 有一张收藏表,里面存储的是用户和图书ID.数据量为1亿.现在要求分页获取所有用户ID(不重复),写下你的sql语句. 表结构大致如下: ...
- 在sqlserver2005/2008中备份数据库,收缩日志文件
---1.先备份数据库(含日志文件) use myhis go backup database myhis to disk='d:\myhis_rzbak' go ---2.设为简单恢复模式 use ...
- NodeJS 初学之安装配置环境
[TOC] 1.环境安装 操作系统: Ubuntu 16.04.2 LTS 1.1安装nvm ryan@ryan-900X5L:~/temp$ curl https://raw.githubuserc ...
- 使用WinDBG调试查看C#内存转储文件
有时候我们想查看一个正在运行的程序内存中的数据,可以在任务管理器将内存状态保存为转储文件,并使用WinDBG验证,这里我们来试试: 0.安装WinDBG 1.首先写个代码用来测试 一个class pu ...
- win10 uwp 入门
UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客. 关于UWP介绍可以参见:http://lib.csdn.net/article/csharp/32451 首先需要申请一 ...
- Python和SQL 2017的强大功能
Python和SQL Server 2017的强大功能 原文来自:https://www.red-gate.com/simple-talk/sql/sql-development/power-py ...
- C语言第一次实验报告
一.实验题目,设计思路,实现方法 7-7 计算火车运行时间(15 分) 4-5 求简单交错序列前N项和(15 分) 4-2-7 装睡(10 分) 思路:7-7须将时间统一单位,化为以分钟计算再将两者相 ...
- FastDFS 简介
FastDFS开源的分布式文件系统,功能包括:文件存储,文件同步,文件访问(文件上传,文件下载等),解决了大容量存储和负载均衡的问题,特别适合以文件为载体的在线服务,如服务网站,视频网站等 FastD ...