详解tomcat架构及工作原理

1,452 阅读9分钟

java 组成

Java包含下面部分:

  • 语言、语法规范。关键字,如: if、for、class等

  • 源代码source code

  • 依赖库,标准库(基础).I第三方库(针对某些应用)。底层代码太难使用且开发效率低,封装成现成的库

  • JVM虚拟机。将源代码编译为中间码即字节码后,再运行在JVM之上

java程序写好后,使用java的编译器,编译成字节码(二进制文件),运行在java虚拟机上,在编译成 各个系统的的执行文件

image.png java实现动态网页功能

java实现动态网页功能

servelt

本质是一段java程序:原理就是在java程序中嵌入 html语言

jsp

JSP本质是提供一个HTML模板,也就是在网页中预留以后填充的空,后续将Java程序运行生成的数据对HTML进行填空就可以了。如果网页布局需要调整!JAVA源代码不需要很大的调整

<%@page language="java" contentType="text/htm1; charset=UTF-8"
    pageEncoding="UTF-8"%>
<! DOCTYPE html>
I<htm1>
<head>
    <meta charset="utf-8">
    <title>jsp例子</title></head>
<body>
本行后面的内容是服务器端动态生成字符串,最后拼接在一起
<%
out. print1n(""你的IP地址" + request.getRemoteAddr(C);
%>
</body></htm1>

JSP是基于Servlet实现,JSP将表现和逻辑分离,这样页面开发人员更好的注重页面表现力更好服务客户。

比如:浏览器第一次请求testjspi时, Tomcat服务器会自动将testisp转化sltest.spjava这么一个类并将该文件编译成cass文件。编译完毕后再运行class文件来应浏览器的请求。如果以后访问testjsp就不再重新编译jsp文件了,直接调用class文件来响应浏览器。后续如果Tomcat检测到SP页面改动了的话,会重新编译 JSP类似于PHP和ASP,前端代码和后端JAVA代码混写在一起需要前端和后端工程师在一起协作才能完成,无法做到真正的前后端分离开发 在web早期的开发中,通常采用的分为两层,视图层和模型层。

image.png

优点:

  1. 平台无关性

    • JSP基于Java语言,因此具有Java的跨平台特性。这意味着JSP应用程序可以在任何支持Java的操作系统和Web服务器上运行,无需担心平台差异。
  2. 强大的功能

    • JSP支持Java语言的全部功能,包括面向对象编程、异常处理、数据库连接等。这使得JSP能够处理复杂的业务逻辑,并实现高度动态化的Web页面。
  3. 可重用性

    • JSP支持自定义标签和模板,通过包含其他JSP页面或Java类,可以实现代码的重用,提高开发效率。
  4. 与Java技术的集成

    • JSP可以与Java的其他技术(如Servlet、JavaBeans、EJB等)无缝集成,这使得开发复杂的Web应用程序变得更加容易。
  5. 安全性

    • Java的安全模型为JSP提供了强大的安全支持。通过Java的安全API,可以轻松地实现用户认证、授权和加密等功能。
  6. 开放性

    • JSP是开放标准,拥有庞大的开发者社区和丰富的开发资源。这使得JSP技术得到了广泛的应用和支持。

JSP的缺点

  1. 性能问题:JSP页面在第一次请求时需要编译成Servlet,这可能导致首次加载时速度较慢。此外,每次请求JSP页面时,实际上都是访问编译后的Servlet,这种基于Servlet的机制在处理大量请求时可能不如其他技术高效。
  2. 可维护性差:JSP页面通常将Java代码和HTML混合在一起,这使得代码难以阅读和维护。对于大型项目,这种混合方式可能增加开发和维护的复杂性。
  3. 不利于前后端分离:JSP将业务逻辑和页面展示紧密耦合在一起,不利于实现前后端分离的开发模式。这可能导致开发团队在协作时产生冲突,降低开发效率。
  4. 安全性问题:JSP容易受到跨站脚本攻击(XSS)等安全漏洞的影响。开发人员需要特别注意输入验证和输出编码等安全问题。
  5. 扩展性差:JSP中的Java代码和HTML混合在一起,难以进行模块化和组件化开发。这可能导致代码重用性低,增加开发成本。

jdk

  • Java SE APl: Java 基础类库开发接口
  • JRE: Java Runtime Environment缩写,指Java运行时环境,包含JVM +Java核心类库
  • JDK: Java Development Kit,即Java语言的软件开发工具包JDK协议基于JRL(JavaResearch License)协议 image.png

image.png

servlet容器工作流程

HTTP服务器不直接调用servlet,而是把请求交给servlet容器来处理。 当客户请求某个资环时,http服务器会用一个servletrequest对象把客户的请求信息封装起来,然后调用servlet容器service方法,servlet容器拿到请求后,根据此URL和servlet映射关系,找到相应的servlet如果没有被加载,就会创建这个servlet,调用servlet的init方法来完成初始化,接着调用servlet的service方法来处理请求,把servletresponse对象返回给HTTP服务器,HTTP服务器把响应发送给客户端。

image.png

Tomcat介绍

Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,Tomcat具有处理HTML页面的功能,它还是一个Servlet和JSP容器

Tomcat整体架构

tomcat要实现两个核心功能 处理socket连接,负责网络字节流request和response对象的转化 加载管理servelet,以及具体处理resquest请求 因此tomcat设计了两个核心组件连接器容器连接器负责对外交流,容器负责内部处理。 image.png

连接器架构

coyote 封装了底层的网络通信(socket 请求及响应处理),为catalina 容器提供了统一的接口,使catalina容器与具体的请求协议及I0操作方式完全解耦。coyote将socket 输入转换封装为 Request 对象,交由catalina 容器进行处理,处理请求完成后Catalina 通过coyote 提供的Response对象将结果写入输出流。

coyote作为独立的模块,只负责具体协议和I0的相关操作,与serv1et 规范实现没有直接关系,因此即便是 Request 和Response 对象也并未实现servlet规范对应的接口,而是在catalina 中将他们进一步封装为servietReauest 和 ServletResponse 。一个容器可以连接多个连接器。

image.png

连接器组件

Endpoint : coyote 通信端点,即通信监听的接口,是具体socket接收和发送处理器,是对传输层的抽象,因此Endpoint用来1)实现TcP/IP协议的。

Tomcat 并没有Endpoint 接口,而是提供了一个抽象类AbstractEndpoint ,里面定义了两个内部类:acceptor和Socketprocessor。Acceptor用于监听socket连接请求,Socketprocessor用于处理接收到的socket请求,它实现Runnable接口,在Run方法里调用协议处理组件processor进行处理。为了提高处理能力,socketprocessor被提交到线程池来执行。

Processor Processor :coyote协议处理接如果说Endpoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议Processor接收来自Endpoint的socket,读取字节流解析成Tomcat Reguest和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象。

Adapter 由于协议不同,客户端发过来的请求信息也不尽相同,tomcat定义了自己的Request类来”存放”这些请求信息,ProtocolHandler接负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的servletRequest,也就意味着,不能用Tomcat Requ作为参数来调用容器,Tomeat设计者的解决方案是引入coyoteAdaptex,这是适配器模式的经典运用,连接器调用coyoteAdaptergSevice方法,传入的是Tomcat Request对象,CqyoteAdapter负责将Tomcat Request转成servletRequest,再调用容器的service方法。 有HTTP(默认端口8080/tcp)、HTTPS(默认端口8443/tcp)、AJP(默认端口8009/tcp)协议的连接器 image.png

容器

名称说明
server服务器,Tomcat运行的进程实例,一个Server中可以有多个service,但通常就一个
service服务,用来组织Engine(引擎)和Connector(连接器,端口)的对应关系,一个service中只有一个Engine
connector连接器,负责客户端的HTTP、HTTPS、AJP等协议连接。一个Connector只属于某一个Engine
Engine即引擎,用来响应并处理用户请求。一个Engine上可以绑定多个Connector
Host即虚拟主机,可以实现多虚拟主机,例如使用不同的主机头区分
Context应用的上下文,配置特定url路径映射和目录的映射关系: url => directory

image.png

tomcat 处理请求过程

-假设来自客户的请求为: http://localhost:8080/test/index.jsp 浏览器端的请求被发送到服务端端口8080,Tomcat进程监听在此端口上。通过侦听的HTTP/1.1Connector获得此请求。

  • Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的响应
  • Engine获得请求192.168.91.100:8080/test/index.jsp,遍历它所有虚拟主机Host
  • Engine匹配到名为localhost的Host。如果匹配不到,就把请求交给该Engine中的defaultHost处理. localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context
  • Host匹配到路径为/test的Context
  • path=/test的Context获得请求index.jsp,在它的mapping table中寻找对应的servlet path = alias
  • Context匹配到URLPATTERN为*.jsp的Sservlet,对应于]spServlet类构造HtpServletRequest对象和HttpServletResponse对象,作为参数调用)spSer let的doGet或doPost方法。

image.png

  • Context把执行完了之后的HttpServletResponse对象返回给Host
  • Host把HttpServletResponse对象返回给Engine
  • Engine把HttpServletResponse对象返回给Connector
  • Connector把HttpServletResponse对象返回给浏览器端