Tomcat核心原理
web概念
软件架构
- c/s:客户端/服务器端
- B/s:浏览器端/服务器端
资源分类
- 静态资源:所有用户访问以后得到的结果都是一样的,成为静态资源.可以直接被浏览器解析.
- 动态资源:每个用户访问到相同的资源后,得到的结果可能不一样,成为动态资源.动态资源被访问以后,需要先转换为静态资源,再返回给浏览器,通过浏览器进行解析.
网络通信三要素
- IP:电子设备(计算机)在网络中的唯一标识.
- 端口:应用程序在计算机中的唯一标识.
- 传输协议:规定了数据传输的协议
- 基础协议:tcp,utp
常见的web服务器
概念
- 服务器:安装了服务器软件的计算机.
- 服务器软件:接收用户的请求,处理请求,做出响应.
- web服务器软件:接收用户请求,处理请求,做除响应.
Tomcat架构
Http工作原理
Tomcat作为一个HTTP服务器主要是接受连接、解析请求数据、处理请求和发送响应这几个步骤。
Tomcat的整体架构
http服务器请求处理
HTTP服务器不直接调用业务类,而是把请求交给容器来处理,容器通过Servlet接口调用业务类。因此Servlet接口和Servlet容器的出现,达到了HTTP服务器与 业务类解耦的目的。而Servlet接口和Servlet容器这一整套规范叫作Servlet规范。
Tomcat按照Servlet规范的要求实现了Servlet容器,同时它们也具有HTTP服务器的功 能。作为Java程序员,如果我们要实现新的业务功能,只需要实现一个Servlet,并把它注册到Tomcat中,剩下的事情就由Tomcat帮我们处理了。
Servlet容器工作流程
当客户请求某个资源时,HTTP服务器会用一个ServletRequest对象把客户的请求信息封 装起来,然后调用Servlet容器的service方法,Servlet容器拿到请求后,根据请求的URL 和Servlet的映射关系,找到相应的Servlet,如果Servlet还没有被加载,就用反射机制创 建这个Servlet,并调用Servlet的init方法来完成初始化,接着调用Servlet的service方法 来处理请求,把ServletResponse对象返回给HTTP服务器,HTTP服务器会把响应发送给客户端
Tomcat整体架构
Tomcat实现的核心功能
- 处理Socket连接,负责网络字节流与Request和Response对象的转化。
- 加载和管理Servlet,以及具体处理Request请求。
连接器-coyote
架构介绍
Coyote 是Tomcat的连接器框架的名称 , 是Tomcat服务器提供的供客户端访问的外部接 口。客户端通过Coyote与服务器建立连接、发送请求并接受响应 。
Coyote 封装了底层的网络通信(Socket 请求及响应处理),为Catalina 容器提供了统一的接口,使Catalina 容器与具体的请求协议及IO操作方式完全解耦。Coyote 将Socket 输 入转换封装为 Request 对象,交由Catalina 容器进行处理,处理请求完成后, Catalina通过Coyote 提供的Response 对象将结果写入输出流 。
Coyote 作为独立的模块,只负责具体协议和IO的相关操作, 与Servlet 规范实现没有直接关系,因此即便是 Request 和 Response 对象也并未实现Servlet规范对应的接口, 而是在Catalina 中将他们进一步封装为ServletRequest 和 ServletResponse 。
IO模型与协议
连接器组件
Endpoint
- coyote通信端点,即通信监听的接口,是具体socket接收和发送处理器,是对传输层的抽象,可以用来实现tcp/ip协议
- Tomcat 并没有EndPoint 接口,而是提供了一个抽象类AbstractEndpoint , 里面定义了两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫作执行器.
Processor
Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象
ProtocolHandler
ProtocolHandler: Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协
议的处理能力。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol ,
AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol ,
Http11AprProtocol。我们在配置tomcat/conf/server.xml 时 , 至少要指定具体的
ProtocolHandler , 当然也可以指定协议名称 , 如 : HTTP/1.1 ,如果安装了APR,那么
将使用Http11AprProtocol , 否则使用 Http11NioProtocol
Adapter
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。
但是这个Request对象不是标准的ServletRequest,也就意味着,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是 适配器模式的经典运用,连接器调用CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容 器的Service方法。
容器-Catalina
Tomcat是一个由一系列可配置的组件构成的Web容器,而Catalina是Tomcat的servlet容器。
Catalina地位
Tomcat 本质上就是一款 Servlet 容器, 因此Catalina 才是 Tomcat 的核心 , 其他模块 都是为Catalina 提供支撑的。 比如 : 通过Coyote 模块提供链接通信,Jasper 模块提供 JSP引擎,Naming 提供JNDI 服务,Juli 提供日志服务
catalina结构
Catalina负责管理Server,而Server表示着整个服务器。Server下面有多个 服务Service,每个服务都包含着多个连接器组件Connector(Coyote 实现)和一个容器组件Container。在Tomcat 启动的时候, 会初始化一个Catalina的实例
Container 结构
Tomcat设计了4种容器,分别是Engine、Host、Context和Wrapper。这4种容器不是平 行关系,而是父子关系。, Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。
容器 | 描述 |
---|---|
Engine | 表示整个catalina的servlet引擎,管理多个虚拟站点,一个service只有一个engine,一个engine有多个host |
Host | 代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主机地址,一个host下可以有多个context |
context | 表示一个web应用程序,可以包含多个wrapper |
wrapper | 表示一个servlet,wrapper为最底层 |
Tomcat启动流程
流程
步骤
- 启动tomcat , 需要调用 bin/startup.bat (在linux 目录下 , 需要调用 bin/startup.sh) 在startup.bat 脚本中, 调用了catalina.bat。
- 在catalina.bat 脚本文件中,调用BootStrap 中的main方法。
- 在BootStrap 的main 方法中调用了 init 方法 来创建Catalina 及初始化类加载器。
- 在BootStrap 的main 方法中调用了load方法 ,在其中又调用了Catalina的load方法。
- 在Catalina的load 方法中 , 需要进行一些初始化的工作, 并需要构造Digester对象, 用 于解析XML。
- 然后在调用后续组件的初始化操作加Tomcat的配置文件,初始化容器组件 ,监听对应的端口号, 准备接受客户端请求
Tomcat请求处理流程
请求流程
Mapper组件的功能就是将用户请求的URL定位到一个Servlet,它的工作原理是: Mapper组件里保存了Web应用的配置信息,其实就是容器组件与访问路径的映射关系, 比如Host容器里配置的域名、Context容器里的Web应用路径,以及Wrapper容器里 Servlet映射的路径,你可以想象这些配置信息就是一个多层次的Map
当一个请求到来时,Mapper组件通过解析请求URL里的域名和路径,再到自己保存的
Map里去查找,就能定位到一个Servlet。请你注意,一个请求URL最后只会定位到一个Wrapper容器,也就是一个Servlet
那上面这幅图只是描述了根据请求的URL如何查找到需要执行的Servlet , 那么下面我们再来解析一下 , 从Tomcat的设计架构层面来分析Tomcat的请求处理
步骤如下
- Connector组件Endpoint中的Acceptor监听客户端套接字连接并接收Socket。
- 将连接交给线程池Executor处理,开始执行请求响应任务。
- Processor组件读取消息报文,解析请求行、请求体、请求头,封装成Request对象。
- Mapper组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context容器、Wrapper容器处理请求。
- CoyoteAdaptor组件负责将Connector组件和Engine容器关联起来,把生成的Request对象和响应对象Response传递到Engine容器中,调用 Pipeline。
- Engine容器的管道开始处理,管道中包含若干个Valve、每个Valve负责部分处理逻辑。执行完Valve后会执行基础的 Valve–StandardEngineValve,负责调用Host容器的Pipeline。
- Host容器的管道开始处理,流程类似,最后执行 Context容器的Pipeline。
- Context容器的管道开始处理,流程类似,最后执行 Wrapper容器的Pipeline。
- Wrapper容器的管道开始处理,流程类似,最后执行 Wrapper容器对应的Servlet对象的 处理方法
Jasper
已淘汰,了解即可
Tomcat服务器配置
Tomcat 服务器的配置主要集中于 tomcat/conf 下的 catalina.policy、catalina.properties、context.xml、server.xml、tomcat-users.xml、web.xml 文件。
Server
Server是server.xml的根元素,用于创建一个Server实例,默认使用的实现类是org.apache.catalina.core.StandardServer
<Server port="8005" shutdown="SHUTDOWN"> ...
</Server>
port : Tomcat 监听的关闭服务器的端口。
shutdown: 关闭服务器的指令字符串
Server内嵌的子元素为 Listener、GlobalNamingResources、Service。
<!‐‐ 用于以日志形式输出服务器 、操作系统、JVM的版本信息 ‐‐>
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!‐‐ 用于加载(服务器启动) 和 销毁 (服务器停止) APR。 如果找不到APR库, 则会 输出日志, 并不影响Tomcat启动 ‐‐>
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!‐‐ 用于避免JRE内存泄漏问题 ‐‐>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<!‐‐ 用户加载(服务器启动) 和 销毁(服务器停止) 全局命名服务 ‐‐>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<!‐‐ 用于在Context停止时重建Executor 池中的线程, 以避免ThreadLocal 相关的内 存泄漏 ‐‐>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
Service
该元素用于创建 Service 实例,默认使用org.apache.catalina.core.StandardService。默认情况下,Tomcat 仅指定了Service 的名称, 值为 “Catalina”。Service 可以内嵌的元素为 : Listener、Executor、Connector、Engine,其中 :Listener 用于为Service添加生命周期监听器, Executor 用于配置Service 共享线程池Connector 用于配置 Service 包含的链接器,Engine 用于配置Service中链接器对应的Servlet 容器引擎。
<Service name="Catalina">
...
</Service>
Executor
默认情况下,Service 并未添加共享线程池配置。 如果我们想添加一个线程池, 可以在下添加如下配置
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" maxThreads="200" minSpareThreads="100" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" threadPriority="5" className="org.apache.catalina.core.StandardThreadExecutor"/>
Connector
Connector 用于创建链接器实例。默认情况下,server.xml 配置了两个链接器,一个支持HTTP协议,一个支持AJP协议。因此大多数情况下,我们并不需要新增链接器配置,只是根据需要对已有链接器进行优化。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Engine
Host 元素用于配置一个虚拟主机, 它支持以下嵌入元素:Alias、Cluster、Listener、Valve、Realm、Context。如果在Engine下配置Realm, 那么此配置将在当前Engine下的所有Host中共享。 同样,如果在Host中配置Realm , 则在当前Host下的所有Context 中共享。Context中的Realm优先级 > Host 的Realm优先级 > Engine中的Realm优先级。
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
...
</Host>
Context
<Context docBase="myApp" path="/myApp">
....
</Context>
以上各个配置详见文档
Web配置
ServletContext 初始化参数
我们可以通过 添加ServletContext 初始化参数,它配置了一个键值对,这样我们可以在 应用程序中使用javax.servlet.ServletContext.getInitParameter()方法获取参数。
<context‐param>
<param‐name>contextConfigLocation</param‐name>
<param‐value>classpath:applicationContext-*.xml</param‐value> <description>Spring Config File Location</description>
</context‐param>
会话配置
用于配置Web应用会话,包括 超时时间、Cookie配置以及会话追踪模式。它将覆盖server.xml 和 context.xml 中的配置。
<session‐config>
<session‐timeout>30</session‐timeout>
<cookie‐config>
<name>JESSIONID</name>
<domain>www.itcast.cn</domain>
<path>/</path>
<comment>Session Cookie</comment>
<http‐only>true</http‐only>
<secure>false</secure>
<max‐age>3600</max‐age>
</cookie‐config>
<tracking‐mode>COOKIE</tracking‐mode> </session‐config>
Servlet配置
Servlet 的配置主要是两部分, servlet 和 servlet-mapping
<servlet>
<servlet‐name>myServlet</servlet‐name>
<servlet‐class>cn.itcast.web.MyServlet</servlet‐class>
<init‐param>
<param‐name>fileName</param‐name>
<param‐value>init.conf</param‐value>
</init‐param>
<load‐on‐startup>1</load‐on‐startup>
<enabled>true</enabled>
</servlet>
<servlet‐mapping>
<servlet‐name>myServlet</servlet‐name>
<url‐pattern>*.do</url‐pattern>
<url‐pattern>/myservet/*</url‐pattern>
</servlet‐mapping>
- servlet‐name : 指定servlet的名称, 该属性在web.xml中唯一。
- servlet‐class : 用于指定servlet类名
- init‐param: 用于指定servlet的初始化参数, 在应用中可以通过HttpServlet.getInitParameter 获取。
- load‐on‐startup: 用于控制在Web应用启动时,Servlet的加载顺序。 值小于0,web应用启动时,不加载该servlet, 第一次访问时加载。
- enabled: true , false 。 若为false ,表示Servlet不处理任何请求。
- url‐pattern: 用于指定URL表达式,一个 servlet‐mapping可以同时配置多个 url‐pattern。
Listener配置
Listener用于监听servlet中的事件,例如context、request、session对象的创建、修改、删除,并触发响应事件。Listener是观察者模式的实现,在servlet中主要用于对 context、request、session对象的生命周期进行监控。在servlet2.5规范中共定义了8中Listener。在启动时,ServletContextListener 的执行顺序与web.xml 中的配置顺序一致, 停止时执行顺序相反。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener‐ class>
</listener>
Filter配置
filter 用于配置web应用过滤器, 用来过滤资源请求及响应。 经常用于认证、日志、加密、数据转换等操作
<filter>
<filter‐name>myFilter</filter‐name>
<filter‐class>cn.itcast.web.MyFilter</filter‐class>
<async‐supported>true</async‐supported>
<init‐param>
<param‐name>language</param‐name>
<param‐value>CN</param‐value>
</init‐param>
</filter>
<filter‐mapping>
<filter‐name>myFilter</filter‐name>
<url‐pattern>/*</url‐pattern>
</filter‐mapping>
Tomcat 管理配置
host-manger
需要在conf/tomcat-
users.xml 中配置,并分配对应的角色
<role rolename="admin‐gui"/>
<role rolename="admin‐script"/>
<user username="itcast" password="itcast" roles="admin‐script,admin‐ gui"/>
manager
<role rolename="manager‐gui"/>
<role rolename="manager‐script"/>
<user username="itcast" password="itcast" roles="admin‐script,admin‐ gui,manager‐gui,manager‐script"/>
JVM配置
JVM内存模型图
Tomcat 集群
简介
由于单台Tomcat的承载能力是有限的,当我们的业务系统用户量比较大,请求压力比较 大时,单台Tomcat是扛不住的,这个时候,就需要搭建Tomcat的集群,而目前比较流程的做法就是通过Nginx来实现Tomcat集群的负载均衡。
负载均衡策略
轮询
最基本的配置方法,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。
upstream serverpool{
server localhost:8888;
server localhost:9999;
}
weight权重
权重方式,在轮询策略的基础上指定轮询的几率
upstream serverpool{
server localhost:8888 weight=3;
server localhost:9999 weight=1;
}
ip_hash
指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直
发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,
可以解决session不能跨服务器的问题。
Session共享方案
ip_hash 策略
一个用户发起的请求,只会请求到tomcat1上进行操作,另一个用户发起的请求只在tomcat2上进行操作。那么这个时候,同一个用户发起的请求,都会通过nginx的ip_hash策略,将请求转发到其中的一台Tomcat上。
Session复制
Session同步的配置如下
- 在Tomcat的conf/server.xml 配置如下
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
- 在Tomcat部署的应用程序 servlet_demo01 的web.xml 中加入如下配置
<distributable/>
- 配置完毕之后, 再次重启两个 Tomcat服务。
上述方案,适用于较小的集群环境(节点数不超过4个),如果集群的节点数比较多的话,通过这种广播的形式来完成Session的复制,会消耗大量的网络带宽,影响服务的性能。
**SSO-**单点登录
单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,也是用来解决集群环境Session共享的方案之一 。
Tomcat 安全
配置安全
- 删除webapps目录下的所有文件,禁用tomcat管理界面
- 注释或删除tomcat-users.xml文件内的所有用户权限
- 更改关闭tomcat指令或禁用
- 定义错误页面
应用安全
在大部分的Web应用中,特别是一些后台应用系统,都会实现自己的安全管理模块(权限模块),用于控制应用系统的安全访问,基本包含两个部分:认证(登录/单点登录)和授权(功能权限、数据权限)两个部分。对于当前的业务系统,可以自己做一套适用于自己业务系统的权限模块,也有很多的应用系统直接使用一些功能完善的安全框架,将其集成到我们的web应用中,如:SpringSecurity、Apache Shiro等。
传输安全
HTTPS介绍
HTTPS的全称是超文本传输安全协议(Hypertext Transfer Protocol Secure),是一种网络安全传输协议。在HTTP的基础上加入SSL/TLS来进行数据加密,保护交换数据不被泄露、窃取。
SSL 和 TLS 是用于网络通信安全的加密协议,它允许客户端和服务器之间通过安全链接通信。
SSL 协议的3个特性
- 保密:通过SSL链接传输的数据时加密的
- 鉴别:通信双方的身份鉴别,通常是可选的,但至少有一方需要验证
- 完整性:传输数据的完整性检查
HTTPS和HTTP的区别
- HTTPS协议需要到证书颁发机构CA申请SSL证书, 然后与域名进行绑定,HTTP不用申请证书
- HTTP是超文本传输协议,属于应用层信息传输,HTTPS 则是具有SSL加密传安全性传输协议,对数据的传输进行加密,相当于HTTP的升级版
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是8080,后者是8443
- HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全
HTTPS协议优势
- 提高网站排名,有利于SEO。谷歌已经公开声明两个网站在搜索结果方面相同,如果一个网站启用了SSL,它可能会获得略高于没有SSL网站的等级,而且百度也表明对安装了SSL的网站表示友好。因此,网站上的内容中启用SSL都有明显的SEO优势。
- 隐私信息加密,防止流量劫持。特别是涉及到隐私信息的网站,互联网大型的数据泄露的事件频发发生,网站进行信息加密势在必行。
- 浏览器受信任。 自从各大主流浏览器大力支持HTTPS协议之后,访问HTTP的网站都会提示“不安全”的警告信息
Tomcat支持HTTPS
生成秘钥库文件
keytool ‐genkey ‐alias tomcat ‐keyalg RSA ‐keystore tomcatkey.keystore
将秘钥库文件 tomcatkey.keystore 复制到tomcat/conf 目录下
配置tomcat/conf/server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true"> <SSLHostConfig certificateVerification="false"> <Certificate certificateKeystoreFile="D:/DevelopProgramFile/apache‐tomcat‐8.5.42‐ windows‐x64/apache‐tomcat‐8.5.42/conf/tomcatkey.keystore" certificateKeystorePassword="itcast" type="RSA" /> </SSLHostConfig> </Connector>
访问Tomcat ,使用https协议
Tomcat 性能调优
对于系统性能,用户最直观的感受就是系统的加载和操作时间,即用户执行某项操作的耗时。从更为专业的角度上讲,性能测试可以从以下两个指标量化。
- 响应时间:如上所述,为执行某个操作的耗时。大多数情况下,我们需要针对同一个操作测试多次,以获取操作的平均响应时间。
- 吞吐量:即在给定的时间内,系统支持的事务数量,计算单位为 TPS。
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~