一起进阶学习JAVA:Tomcat

什么是Tomcat

Tomcat 是一个开源的轻量级Web应用服务器,可实现JavaWeb程序的装载,它也具有传统的Web服务器的功能,也可以说Tomcat是一个Servlet容器。

Tomcat系统架构

Tomcat主要服务区B/S架构:浏览器客户端与服务器端交互。

浏览器访问服务器流程

在这里插入图片描述
浏览器访问服务器使用的是Http协议,Http是应用层协议,用于定义数据通信格式。数据传输使用的是TCP/IP协议

Tomcat请求处理过程

  1. 用户通过浏览器向网站发送Http请求。
  2. Http服务器接收到用户请求。
  3. Http服务器将请求交予Servlet容器。
  4. Servlet容器通过Servlet接口调用业务类。
  5. 返回请求数据。

Tomcat Servlet容器处理流程

当用户请求某个URL资源时

  1. HTTP服务器会把请求信息使用ServletRequest对象封装
  2. Servlet容器根据URL喝Servlet的映射关系调用具体的Servlet
  3. 如果Servlet还没有被加载,就使用反射机制创建这个Servlet并且调用init方法来初始化
  4. 调用该Servlet中的service方法来处理请求
  5. 使用ServletResponse对象丰庄返回数据
  6. 把ServletResponse对象返回给HTTP服务器
  7. HTTP服务器将响应发送给客户端

Tomcat系统总体架构

Tomcat有两个非常重要的功能

  1. 和客户端浏览器进行交互,进行Socket通信,将字节流喝Request以及Response等对象进行转换
  2. Servlet容器处理业务逻辑

因此Tomcat设计了两个核心组件连接器(Connector)容器(Container)来完成Tomcat的两大核心功能

  • 连接器,负责对外交流,处理Socket连接,负责网络字节流与RequestResponse对象的转化;
  • 容器,负责内部处理,夹在和管理Servlet,以及具体的处理Request请求

Tomcat连接器组件Coyote

什么是Coyote

Coyote是Tomcat中连接器组件,是对外的接口。客户端通过Coyote与服务器建立连接、发送请求、接受请求。

  1. Coyote封装了底层的网络通信(Socket请求及响应处理);
  2. Coyote使Catalina容器(容器组件)与具体的请求协议以及IO操作方式完全解耦
  3. Coyote将Socket输入转换封装为Request对象,进一步封装后交由Catalina容器进行处理,处理请求完成后,Catalina通过Coyote提供的Response对象将结果写入输出流
  4. Coyote负责的是具体协议(应用层)和IO(传输层)相关内容
    在这里插入图片描述
    Tomcat Coyote支持多种应用层协议和I/O模型
应用层应用层协议描述
HTTP/1.1这是大部分Web应用采用的访问协议
AJP用于和WX集成(如Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3
HTTP/2HTTP2.0大幅度的提升了Web性能。下一代HTTP协议,自8.5以及9.0版本之后开始支持
传输层IO模型描述
NIO非阻塞I/O,采用Java NIO类库实现
NIO2异步I/O,采用JDK7最新的NIO2类库实现
APR采用Apache可移植运行库实现,是C/C++编写的本地库。如果选择该方案,需要单独安装APR库

在8.0之前,Tomcat默认采用的I/O的方式为BIO,之后改为NIO。无论NIO、NIO2还是APR,在性能方面均优于以往的BIO。如果采用APR,伸直可hi达到Apache HTTP Server的影响性能

Coyote的流程

在这里插入图片描述

Coyote 组件及作用

组件作用描述
EndPointEndPoint是Coyote通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对象传输层的抽象,因此EndPoint是用来实现TCP/IP协议的
ProcessorProcessor是Coyote协议处理接口,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接受来自EndPoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象
ProtocolHandlerCoyote协议几口,通过EndPoint和Processor实现针对具体协议的处理能力。Tomcat按照协议和I/O提供的实现类: AjpNioProtocol, AjpAprProtocol҅ ,AjpNio2Protocol ,Http11NioProtocol,Http11Nio2Protocol ,Http11AprProtocol
Adapter由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来封装这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用CoyoteAdapter的Service方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转换成ServletRequest对象,然后再调用容器

Tomcat Servlet容器Catalina

Tomcat是一个由一系列可配置(conf/server.xml)的组件构成的Web容器,而Catalina是Tomcat的Servlet容器。
Catalina是Tomcat的核心,其他模块都是为Catalina提供支撑的
在这里插入图片描述

Servlet容器Catalina的结构

在这里插入图片描述
我们可以认为整个Tomcat就是一个Catalina实力,Tomcat启动的时候会初始化这个实力,Catalina实力通过加载server.xml来完成创建一个Server,Server创建并管理多个服务,每个服务又可以又多个Connector和一个Container

  • Catalina:负责解析Tomcat的配置文件(server.xml)用于创建服务器Server组件并进行管理
  • Server:服务器表示整个Catalina Servlet容器以及其他组件,负责组装并启动Servlet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式
  • Service:Service是Server的内部组件,一个Server包含多个Service。它将多个Connerctor组件绑定到一个Container
  • Container:Container容器负责处理用户Servlet请求,并返回对象给web用户的模块

Container 组件的具体结构

Cintainer组件下有集中具体的组件,分别是Engine、Host、Context和Wrapper。具体配置在conf/server.xml

  • Engine:表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最懂只能有一个Engine,但是一个Engine可以包含多个Host
  • Host:代表一个虚拟主机或者站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可以包含多个Context
  • Context:表示一个Web应用成语,一个Web应用可以包含多个Wrapper
  • Wrapper:表示一个Servlet,Wrapper作为容器中的最底层,不能包含子容器

Tomcat服务器核心配置

Tomcat作为服务器的配置,主要是server.xml文件的配置,server.xml中包含了Servlet容器的相关配置,即Catalina的配置

主要标签如下

<!-- Server 根元素,创建一个Server实例,子标签有Listener,GlobalNamingResources,Service -->
<Server>
	<!-- 定义监听器 -->
	<Listener />
	<!-- 定义服务器的全局JNDI资源 -->
	<GlobalNamingResources />
	<!-- 定义Service服务,一个Server标签可以有多个Service服务实例 -->
	<Service />
</Server>

Server标签

<!--  port:关闭服务器的监听端口
		shutdown:关闭服务器的指令字符串--> 
<Server port="8005" shutdown="SHUTDOWN">  
	<!--  以日志形式输出服务器、操作系统、JVM的版本信息  -->
	<Listener className="org.apache.catalina.startup.VersionLoggerListener" />  
	<!-- Security listener. Documentation at /docs/config/listeners.html  
	<Listener className="org.apache.catalina.security.SecurityListener" />  -->  
	<!--APR library loader. Documentation at /docs/apr.html -->  
	<!--  加载(服务器启动)和销毁(服务器停止)APR。如果找不到APR类库,则会输出日志,并不影响 Tomcat启动 --> 
	<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />  
	<!-- Prevent memory leaks due to use of particular java/javax APIs-->  
	<!-- 避免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" />      
	<!-- Global JNDI resources       
	Documentation at /docs/jndi-resources-howto.html       
	GlobalNamingResources 中定义了全局命名服务  -->  
	<GlobalNamingResources>    
		<!-- Editable user database that can also be used by         
		UserDatabaseRealm to authenticate users    -->    
		<Resource name="UserDatabase" auth="Container"              
				  type="org.apache.catalina.UserDatabase"              
				  description="User database that can be updated and saved"              
				  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"              
				  pathname="conf/tomcat-users.xml" />  
				  
	</GlobalNamingResources>
	<!-- A "Service" is a collection of one or more "Connectors" that share       
	a single "Container" Note:  A "Service" is not itself a "Container",       
	so you may not define subcomponents such as "Valves" at this level.       
	Documentation at /docs/config/service.html   -->  
	<Service name="Catalina">    
			...  
	</Service> 
  </Server>

Service标签

<!-- 该标签用于创建Service实例,默认使用  org.apache.catalina.core.StandardService
Tomcat默认仅指定了Service的名称,值为Catalina
Service有如下子标签
	Listener:用于为Service添加生命周期监听器
	Executor:用于配置Service共享线程池
	Connector:用于配置Service包含的链接器
	Engine:用于配置Service中链接器对应的Servlet容器引擎
-->  
<Service name="Catalina">  
	... 
</Service>

Executor标签

<!-- name配置线程池名称,用于Connector中指定
	namePrefix配置线程的名称前缀,一般线程名为namePrefix + threadNumber
	maxThreads配置线程池最大线程数
	minSpareThreads配置活跃线程数,也可以说是核心线程数,核心线程不会被销毁
	maxIdleTime配置线程空闲时间,超过该时间后空闲线程会被销毁,单位毫秒,默认6000(1分钟)
	maxQueueSize配置先前最大线程排队数
	prestartminSpareThreads配置启动线程池时是否启动minSpareThreads线程,false为不启动
	threadPriority配置有限期,默认为5,值从1-10,数字越大优先级越高
	className配置线程池实现类,如果想自定义需要实现org.apache.catalina.Executor接口---->
<Executor name="commonThreadPool"   
		  namePrefix="thread-exec-"    
		  maxThreads="200"    
		  minSpareThreads="100"    
		  maxIdleTime="60000"    
		  maxQueueSize="Integer.MAX_VALUE"    
		  prestartminSpareThreads="false"     
		  threadPriority="5"    
		  className="org.apache.catalina.core.StandardThreadExecutor"/>

Connector标签

Connector标签用于创建链接器实例,默认有2个,一个支持HTTP协议,一个支持AJP协议

一般情况下我们不需要新增,只需要对已有的进行优化

<!-- 
	port:监听端口号,如果设置为0则Tomcat会随机分配一个端口
	protocol:支持的访问协议,默认为HTTP/1.1
	connectionTimeout:接受连接后的等待超时时间,单位为毫秒,-1为不超时
	redirectPort:重定向端口,当前Connector不支持SSL请求,当接收到了符合security-constraint 约束的需要SSL传输的请求会重定向该端口
	
-->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

还可以使用共享线程池

<Connector port="8080"             
		protocol="HTTP/1.1"          
		executor="commonThreadPool"          
		maxThreads="1000"             
		minSpareThreads="100"             
		acceptCount="1000"            
		maxConnections="1000"            
		connectionTimeout="20000"          
		compression="on"            
		compressionMinSize="2048"            
		disableUploadTimeout="true"            
		redirectPort="8443"            
		URIEncoding="UTF-8" /> 

Engine标签

Engine标签标识Servlet引擎

<!--
	name:指定Engine名称,默认为Catalina
	defaultHost:默认使用的虚拟主机名称,当客户请求指向的主机无效时交由默认的虚拟主机处理
 -->
<Engine name="Catalina" defaultHost="localhost">
 ...
</Engine>

Host标签

Host标签用于配置一个虚拟主机

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
 ...
</Host> 

Context标签

Context用于配置一个Web应用

<Host name="www.xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
	<!--
	 docBase:Web应用录或者War包的部署路径。可以是绝对路径,也可以是相对于 Host appBase的
	相对路径。
	 path:Web应用的Context 路径。如果我们Host名为localhost, 则该web应用访问的根路径为:
	 http://localhost:8080/web_demo。
	-->
 <Context docBase="/xxx/xxx/web_demo" path="/web3"></Context>

 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
 prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值