一、Tomcat启动时到底对我们的应用程序做了什么?

当我们把一个应用程序的war包放到Tomcat的webapps目录后,启动Tomcat,然后就可以通过浏览器发送Http请求访问该war包内的Servlet了。
这个过程包括:
1、启动Tomcat
2、Tomcat处理Http请求
而启动Tomcat的目的就是为了处理Http请求。

一个Http请求通常是这样子的:
http://localhost:8080/app/helloServlet
这个请求包括:

协议:http
主机名:localhost
端口:8080
应用名:app
Servlet名:helloServlet

我们通俗点来理解这个Http请求就是:浏览器通过Http协议,请求localhost:8080上的myapp应用内的helloServlet。

Tomcat架构俯视图:

二、那分析这个Http请求有什么用呢?和Tomcat有什么关系?

当然有关系,上面这个Http请求中的localhost:8080其实代表的就是Tomcat。我们一个应用程序想要从外部接收网络数据,那就要绑定一个端口,这个跟TCP协议有关系,外部请求发送给该端口,就能被对于的程序所接收到。Tomcat也是这样,所以,Tomcat默认绑定的就是8080。

所以上面这个Http请求首先是被Tomcat接收到,然后去解析这个请求。
解析这个请求包括:

请求所使用的方法,是GET,还是POST,还是其他
所请求的应用与Servlet的名字是什么
请求所携带的数据

当Tomcat把从8080端口获取的请求解析完成后,它就应该根据应用名和Servlet名字去找Servlet实现类了,只有找到Servlet实现类才能真正执行Servlet里面的doGet或doPost方法。

所以,这里又分两步:

根据请求中的应用名和Servlet名怎么找到对应的Servlet实现类呢
怎么执行Servlet实现类中跟请求对应的方法呢

首先关于第二点,很简单:可以用***反射***
那么对于第一点该怎么实现呢?
其实也很简单,要么默认,要么映射。
默认的意思就是,请求中的Servlet名就是类名,这种可行,但是不好用,一个类还有包名的,万一在一个应用中,存在不同的包下存在名字相同的Servlet,这个时候就尴尬了。
所以最好的方式就是映射,一个Servlet名对应一个Servlet实现类。这也就是为什么我们在定义Servlet时,一定要做一个mapping关系,不管是通过@WebServlet注解还是在web.xml中,都需要配置一个mapping才能被访问到。

所以,Tomcat通过监听端口,获取数据,然后解析数据,根据请求url找到对应的Servlet实现类,然后通过反射执行Servlet实现类中的方法

这个流程并不难,如果我们自己实现,30分钟内可能就能实现出来这么一个功能,这也是Tomcat的主线功能,那么Tomcat复杂在哪呢?
其实还是复杂在这条主线,这条主线再拆分一下就是两步:

获取并解析数据
寻找并执行Servlet

tomcat容器对比:

三、Servlet

我们在来细想一下这里的第二步:寻找并执行Servlet

我们通常说Tomcat是一个Servlet容器,到底体现在哪,怎么体现的呢?
我们得先来理解一下Servlet,Servlet=Server+Applet,表达的意思就是运行在服务端的应用程序,它跟运行在客户端的应用程序是相对的,运行在客户端的应用程序,可以随着用户的操作而发生变化,而运行在服务端的应用程序,用户是不能直接操作的,你只能通过发送网络请求来操作它,这就是Servlet的由来。这也就是为什么Servlet规范里会定义ServletRequest,ServletResponse接口,都是跟请求相关的,所以,Servlet其实就为Java程序员方便处理请求和响应的一种抽象,作为Java程序员,你只需要通过定义Servlet,然后接收到的ServletRequest对象就代表请求,而不用关心ServletRequest具体的实现类是什么,是谁实现的,都不用关系,只要知道这个对象代表一个请求即可。
所以谁来实现这些接口呢?大家自然就能想到了,是Tomcat、Jetty这些了。比如Tomcat中对应的请求实现类是RequestFacade,我们在Servlet中进行强制转化是没有问题的,比如这么写:

@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {RequestFacade requestFacade = (RequestFacade) req;resp.getWriter().println("luban annotation servlet");}

我们重新理解了Servlet之后,就可以再来理解Tomcat了,Tomcat确实是一个容器,但是是一个分层的容器。因为一个Servlet代表一个功能,一个应用中可以有多个Servlet,所以在Tomcat中存在Context容器,Context容器中收纳Servlet,Context就代表应用,也就是应用上下文,然后我们的应用是部署在主机上的,所以Tomcat中存在Host容器,一个Host容器中可以容纳多个Context容器,再继续,我们可能是多个主机所提供的功能属于同一范畴的,所以在Tomcat中,在Host之上还有一层Engine。所以我们说的容器包括:Engine、Host、Context。

而Tomcat除开实现了这个层级结构之外,还提供了一些辅助功能。
既然现在容器分层了,所以一个请求在寻找Servlet的过程中,就会经过每一层容器,那么每层容器在这个过程中都可以去做一些事情,并且允许用户自定义这些事情,比如可以在Host层去指定:所有请求该Host的请求都将日志打印到hostname.log文件中,或者所有请求该Host的请求都由该Host添加一下参数,其他容器也类似,这其实就是一种责任链模式,Tomcat中实现了这种模式,是通过:Pipeline和Valve实现的。

好,这是关于容器的分析。
接下来我们再来分析一下Tomcat是怎么解析请求的,上文我们分析了,Tomcat实际上就是把接收到的请求转化成RequestFacade对象,最后把这个对象传递给Servlet。
那么Tomcat的数据从哪来的呢?上文中我们一直默认Tomcat接收的是Http请求,那么这个Http请求是怎么到达Tomcat的呢?总不是凭空飞过来了的吧。
大家应该想到了,是通过网线传过来的,所以我们要分析Tomcat是怎么接收到Http请求,就要分析网络传输协议了。
首先,我们为什么需要网络传输协议呢?
网络是用来传输数据的,比如现在主机A有一份数据要发送给主机B,那么主机A在拥有数据的同时还是要知道主机B的地址,也就是IP,所以现在相当于主机A上要有:数据+对方IP地址

四、流程图

Tomcat:

(1)Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container;
(2) Server掌管着整个Tomcat的生死大权;
(4)Service 是对外提供服务的;
(5)Connector用于接受请求并将请求封装成Request和Response来具体处理;
(6)Container用于封装和管理Servlet,以及具体处理request请求;

Connector:

四个子容器:

(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
(2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
(3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封装着一个Servlet;

上述的包含关系或者说是父子关系,都可以在tomcat的conf目录下的server.xml配置文件中看出,下图是删除了注释内容之后的一个完整的server.xml配置文件(Tomcat版本为8.0)

更多详情

五、那么Tcp是用来干什么的呢?

回到上面的场景,主机A想把数据发送给主机B,那谁来保证数据能可靠的到达对方呢?这就是Tcp协议所要做的事情。
那Http协议又是怎么回事呢?我们上面接收的Ip,Tcp都是跟传输相关的,而Http是跟应用相关的,是跟数据所表达的意义相关的,比如,主机A发一份数据给主机B之后,主机B接收到这份数据后,它要干什么呢?它要执行什么动作呢?这就是Http协议所要表达的,通过在数据中增加一些有意义的元素,比如请求方法,这样数据接收方能更快的根据Http协议解析数据,完成对应的动作。
解析的比较粗,因为这不是本文的重点,我的重点是,那么谁来实现Http协议,谁来实现Tcp协议呢?
答案是:操作系统来实现Tcp协议,比如Linux、Windows,运行在操作系统之上的其他应用程序来实现Http协议,比如浏览器、Tomcat。
比如Linux的源码中就有关于Tcp协议的实现,包括三次握手,四次挥手,都是通过c语言来实现的。那么浏览器它依照Http协议定义好数据之后,怎么利用Tcp协议发送出去呢?Tomcat怎么利用Tcp协议接收数据呢?
浏览器能不能直接调用操作系统中实现TCP协议关于发送数据的函数呢?Tomcat能不能调用对应接收数据的函数呢?
原理上是可以的,但是就像我们开发业务一样,我们不会将真正实现业务的方法直接暴露给其他人调用,而会提供一个接口,操作系统也一样,这个接口就是Socket。
所以Tomcat是通过Socket从操作系统获取数据的,拿到数据后进行解析。
而Tomcat从操作系统系统拿数据又有几种方式,也就是IO模型:BIO,NIO,AIO,这些不同的模式Tomcat都是支持的,只需要在server.xml中进行配置即可。
简单记录了一下关于Tomcat的随笔,其实关于TSocket、IO模型可以写得更多一点,限于篇幅,本篇就到此为止吧,下次继续。

Tomcat底层原理相关推荐

  1. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  2. Tomcat 架构原理到架构设计,写得非常好!

    Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这么多年,已经比较成熟稳定.在如今『追新求快』的时代,Tomcat 作为 Java Web 开发必备的工具似乎变成了『熟悉的陌生人』,难道说 ...

  3. Servlet底层原理、Servlet实现方式、Servlet生命周期

    Servlet简介 Servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. Servlet的特点 (1)Servlet对像,由Servlet容器 ...

  4. IOC容器(底层原理解读)

    IOC的概念和原理 目录 IOC的概念和原理 1.什么是IOC (1)控制反转: (2)使用IOC的目的:降低耦合度 (3)IOC解耦过程图解 2.IOC的底层原理 3.IOC接口 (1)IOC思想 ...

  5. 网络协议从入门到底层原理(8)HTTPS(成本、通信过程、TLS1.2的连接,配置服务器HTTPS)

    HTTPS SSL / TLS OpenSSL HTTPS的成本 HTTPS的通信过程 TLS 1.2 的连接(ECDHE密钥交换算法) ① Client Hello ② Server Hello ③ ...

  6. 网络协议从入门到底层原理(6)应用层 - 域名、DNS、DHCP、HTTP(ABNF、HTTP报文格式、请求方法、头部字段、状态码、跨域)、代理、CDN

    应用层 域名( Domain Name)- 顶级域名.二级域名 DNS - DNS服务器.常用命令 DHCP(DISCOVER.OFFER.REQUEST.ACKNOWLEDGE) HTTP HTTP ...

  7. JAVA程序员的堕落:只知框架不懂底层原理

    我曾在多个场合撰文说过,现在培训出来的企业Java开发兵团只知道使用某种框架,但完全不知道这些框架的底层原理.今天早上,在依次对三个职位的应聘者面试中,我又再次见到了这种情形. 我们的顾问公司收到了一 ...

  8. 眼见为实:被误导的Tomcat工作原理

    Tomcat的主要工作是:监听用户通过浏览器发送的网络请求,然后把请求连接上你的应用程序,做信息交换.在这个过程中,Tomcat里有acceptor.poller. exec等等这些线程在做这个工作. ...

  9. 深度学习Spring5底层原理(黑马学习随笔)

    学习随笔简介 跟随着黑马满老师的<黑马程序员Spring视频教程,全面深度讲解spring5底层原理>学习,视频教程地址:黑马程序员Spring视频教程,全面深度讲解spring5底层原理 ...

  10. Request(HTTP请求对象)的笔记和底层原理

    Request笔记以及底层原理 1.HTTP协议 2.学会识别请求 3.Request请求对象 4.Request是域对象 5.使用域对象进行数据传递(请求转发) 6.Request底层原理图 1.H ...

最新文章

  1. mysql 数据类型 int_MySQL数据类型 int(M) 表示什么意思?
  2. Linux NB的单行命令
  3. 鸿蒙系统海外名称,新商标表明华为鸿蒙系统在海外或叫做“Harmony OS”
  4. java 读取 文本块_Java 13:文本块
  5. 7.MongoDB与python交互
  6. Vue学习笔记--Vue双向绑定实现原理
  7. MyEclipse-6.5注冊码生成器源代码
  8. java程序的开发工具是jdk,分享面经
  9. 用浏览器控制台查看ajax请求
  10. 找回 Windows 丢失的拨号密码
  11. linux ping 不通 arp incomplete,关于show arp表,显示Incomplete问题
  12. CAD转换PDF文件失败,打开后内容是空白的
  13. 分层确定性钱包(HD Wallets)
  14. 安装北洋雷达驱动以及可能遇到的问题
  15. Vim常用操作,normal模式、insert模式和visual模式
  16. 从GraalVM到Quarkus系列-B002篇-Quarkus中的字节码框架gizmo
  17. 语义计算_语义多态性如何在量子计算中起作用
  18. CSS基础标签属性及案例
  19. 51个Python鲜为人知的秘密特性,老司机看完都惊叹不已
  20. c语言595驱动数码管,74hc595驱动4位数码管程序解析 - 74hc595驱动4位数码管电路连接图及程序解析...

热门文章

  1. 小学生c语言编程入门教程_学生编程语言
  2. ie8 ajax提交表单,IE8下 ajaxSubmit兼容问题
  3. 虚拟光驱 DAEMON Tools Lite 安装笔记
  4. r语言如何下载carzip包本地安装_R语言安装R package的2种方法
  5. JavaScript案例分享+复盘——小米闪购界面
  6. Mac WebStorm 破解
  7. iPhone iPad游戏应用开发视频教程
  8. java面试题,各大企业常见的java笔试题及答案(精华)
  9. 安卓工作室 日志设置
  10. 音乐网站Spotify将融资4亿美元,估值84亿美元