一、Tomcat基本原理
Tomcat两个核心组件:Connector(连接器)和Container(容器),Connector:处理Socket连接,负责网络字节流与Request和Response对象的转化;Container:加载和管理Servlet,处理具体的Request请求。
1.1 连接器Coyote
连接器架构
Coyote是Tom猫连接器框架的名称,是Tom猫服务器提供给客户端访问的外部接口。客户端通过Coyote与服务器建立连接、发送请求并接收响应。
Coyote封装网络通信(Socket请求及响应处理),为Catalina容器提供统一的接口,是Catalina容器与具体的请求协议以及IO操作方式完全解耦。Coyote将Socket输入转换封装为Request对象,交由Catalina容器处理,处理请求完,Catalina通过Coyote提供的Response对象将结果写入输出流。
Coyote作为独立的模块,只负责具体协议和IO的相关操作,与Servlet规范没有直接关系,因此即便是Request和Response对象也并未实现Servlet规范对应的接口,而是在中Catalina将他们进一步封装为ServletRequest和ServletResponse。
Tom猫为了支持实现支持多种I/O模型和应用层协议,一个容器可能对接多个连接器。单独的连接器或容器都不能对外提供服务,需要组装起来才能工作,组装后的就是Service组件。Tom猫内可能有多个Service,这样的设计也是出于灵活考虑,通过在Tom猫中配置多个Service可以实现通过不同的端口来访问同一台机器上部署的不同应用。
IO模型与协议
连接器组件
EndPoint
:coyote通信端点,即通信监听接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议。Tom猫并没有EndPoint接口,而是提供了一个抽象类AbstractEndPoint,里面定义两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力SocketProcessor被提交到线程池来执行。而这个线程池叫执行器(Executor)。
Processor
:coyote协议处理接口,如果说EndPoint是用来实现TCP/IP协议,那么Processor就是用来实现HTTP协议的,Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Reqruest/Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层的抽象。
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定义了自己的Reqruest类来“存放”这些请求信息。ProcessorHandler接口负责解析请求并生成Tomcat Request。但是这个Request对象不是标准的ServletRequest,也就意味着,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入coyoteAdapter,这是适配器模式的经典运用,连接器调用coyoteAdapter的sevice方法,传入是Tomcat Request对象,coyoteAdapter负责将Tomcat Request转成ServletRequest,在调用容器的service方法。
1.2 容器Catalina
Tomcat是一个由一系列可配置的组件构成的Web容器,而Catalina是Tomcat的Servlet的容器。
Tomcat本质就是一款Servlet容器,因此Catalina才是Tomcat的核心,其他模块都是为Catalina提供支撑。如,coyote模块提供链接通信,Jasper模块提供JSP引擎,Naming提供JNDI服务,Juli提供日志服务。
Catalina是Servlet容器实现,包含了之前讲到的所有组件,以及安全、会话、集群、管理等Servlet容器架构。它通过轻松耦合的方式集成coyote,以完成按照请求协议进行数据读写。同时,它还包括我们的启动入口、Shell程序等。
Catalina负责管理Server,而Service表示着整个服务器。Server下面有多个Service,每个服务都包含着多个连接器组件Connector(coyote实现)和一个容器组件Container。在Tomcat启动的时候,会初始化一个Catalina的实例。
1.3 Tomcat启动流程
由于所有的组件均存在初始化、启动停止等声明周期方法,拥有生命周期管理的特征,所以Tomcat在设计的时候,基于声明周期管理抽象成了一个接口Lifecycle,而组件Server、Service、Container、Executor、Connector组件,都实现了一个生命周期的接口,从而具有了生命周期中的核心方法:init()、start()、stop()、destory()。
1.3 Tomcat处理请求流程
二、Jasper
2.1 Jasper简介
Jasper模块是Tomcat的JSP核心引擎,JSP本质上就是一个Servlet。Tomcat使用Jasper对JSP语法进行解析,生成Servlet并生成Class字节码,用户在进行访问JSP时,会访问Servlet,最终将访问的结果直接响应在浏览器。另外,在运行的时候,Jasper还会检测JSP是否修改,如果修改,则会重新编译JSP文件。
2.2 JSP的编译方式
2.2.1 运行时编译
Tomcat并不会在启动Web应用的时候自动编译JSP文件,而是在客户端第一次请求时,才编译需要访问的JSP文件。
2.2.2 编译结果
2.2.3 预编译
除了运行时编译,我们还可以直接在Web应用启动时,一次性将Web应用中的所有的JSP页面一次性编译完成。在这种情况中,Web应用运行过程中,便可以不必再进行实时编译,而是直接调用JSP页面对应的Servlet完成请求处理,从而提升系统性能。
Tomcat提供一个Shell程序JspC,用于支持JSP预编译,而且在Tomcat的安装目录下提供了一个catalina-tasks.xml文件声明了Tomcat支持Ant任务,因此,我们很容易使用Ant来执行JSP编译。
2.3 JSP的编译原理
查看编译的java文件即可。
三、Tomcat配置
3.1 server.xml
3.2 web.xml
WEB应用的名字
WEB应用的描述
context-param元素声明应用范围内的初始化参数
contextConfigLocation
/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml
过滤器将一个名字与一个实现javax.servlet.Filter接口的类相关联
一旦命名了一个过滤器,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联
事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。
如Log4j这个广泛使用的监听和
org.springframework.web.context.ContextLoaderListener
在向servlet或JSP页面制定初始化参数或定制URL时,必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。
服务器一般为servlet提供一个缺省的URL:http://host/webAppPrefix/servlet/ServletName。但是,常常会更改这个URL,以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时,使用servlet-mapping元素
如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。 可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值,或者可利用session-config元素制定缺省超时值
如果Web应用具有想到特殊的文件,希望能保证给他们分配特定的MIME类型,则mime-mapping元素提供这种保证
指示服务器在收到引用一个目录名而不是文件名的URL时,使用哪个文件(其实就是欢迎界面或者说入口界面一般为index.*)
在返回特定HTTP状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
对标记库描述符文件(Tag Libraryu Descriptor file)指定别名。此功能使你能够更改TLD文件的位置, 而不用编辑使用这些文件的JSP页面。
声明与资源相关的一个管理对象。
声明一个资源工厂使用的外部资源。
制定应该保护的URL。它与login-config元素联合使用
指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。
给出安全角色的一个列表,这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易
声明Web应用的环境项
四、Tomcat管理配置
从早期的Tomcat版本开始,就提供了Web版的管理控制台,他们是两个独立的Web应用,位于webapps目录下。Tomcat提供的管理应用有用于管理HOST的host-manager和用于管理Web应用的manager。
3.1 host-manager
Tomcat启动之后,可以通过http://localhost:8080/host-manager/html访问该Web应用。host-manager默认添加了访问控制权限,当打开网址时,需要输入用户名和密码(conf/tomcat-users.xml中配置)。所以要想访问页面,需要在conf/tomcat-users.xml中配置,并分配对应的角色:
1.admin-gui:用于控制页面访问权限。
2.admin-script:用于控制以简单文本的形式进行访问。
3.2 manager
manager的访问地址http://localhost:8080/manager,同样,manager也添加了页面访问控制。
五、Tomcat集群SSO
六、Tomcat安全
6.1 配置安全
1.删除webapps目录下的所有文件,禁用tomcat管理界面。
2.注释或删除tomcat-users.xml文件内的所有用户权限。
3.更改关闭tomcat指令或禁用。
6.2 应用安全
大部分的Web应用,都会有自己的安全管理模块,用于控制应用系统的安全访问,基本包含两个部分,认证和授权。对于当前的业务系统,可以自己做一套适用于自己业务系统的权限模块,也有很多系统直接使用一些功能完善的安全框架,将其集成在Web中,例如:SpringSecurity、 Apache Shiro等。
6.3 传输安全
HTTPS(全称:Hyper Text Transfer Protocol over SecureSocket Layer),是一种网络安全传输协议。在HTTP基础上加入SSL/TLS来进行数据加密,保护数据不泄漏、窃取。
SSL 和 TLS是用于网络通信安全的加密协议,它允许客户端和服务器之间通过安全链接通信。SSL协议3特性“
1.保密:通过SSL链接传输的数据加密。
2.鉴别:通信双方的身份鉴别,通常是可选的,但至少有一方需要验证。
3.完整:传输数据的完整性检查。
从性能角度考虑,加密解密是一项昂贵的处理,因为尽量不要将整个Web应用采用SSL链接,实际部署中,选择有必要进行安全加密的页面采用SSL通信。
HTTP和HTTPS主要区别:
1.HTTPS协议需要到证书办法机构CA申请SSL证书,然后与域名进行绑定,HTTP不用申请。
2.HTTP是超文本传输协议,属于应用层信息传输,HTTPS则是具有SSL加密安全传输协议,对数据的传输进行加密,相当于HTTP的升级版。
3.HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是8080,后者是8443。
4.HTTP的连接很简单,是无状态的,HTTPS是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比HTTP协议安全。