Tomcat初始篇:Tomcat国之重器

一.写作目的

为什么要研究tomcat容器勒,博主最近在作知识归纳总结,写到架构篇的时候,用nginx对tomcat容器应用进行负载,博主这时候想到,应用离不开并发,面试、工作、压测、性能优化等等都离不开tomcat,只要明白tomcat工作原理,以及它是如何处理并发?跟服务器内存、cpu的关联?一个tomcat能支撑多少并发?如何集成多个tomcat提高应用并发能力,提升客户满意度?并发的瓶颈在哪里?清清楚楚的知道这些知识点以后,以后做架构,写具体功能,不至于茫然,我这到底能处理多少并发,客户要求多少并发量,我如何提供并发量,为什么我的接口压着压着就崩了等等,这些技术本来应该是自己很早之前就应该了解的,起初没有想这么多,还是做开发时间长了,回顾自己的知识体系,觉得还是很有必要去深究一番。那么开始我们的tomcat研究之旅。

二.概述以及运行原理

Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器。
如果你学过html,css,你会知道你写的页面只能自己访问,别人不能远程访问你写的页面,Tomcat就是提供能够让别人访问自己写的页面的一个程序。
在这里插入图片描述Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。

Service主要包含两个部分:Connector和Container。以及其他组件。

  1. Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container;
  2. Server指整个tomcat容器,负责启动和管理各个Service,同时监听8005端口发过来的shutdown命令用来关闭整个容器,掌管着整个Tomcat的生死大权;
  3. Service 是对外提供基于组件的外部服务;
  4. Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化;是与外部事件的连接器,监听固定的端口,接收外部请求。将请求传递给Container。并且将Container的处理结果反馈给外部。
  5. Container用于封装和管理Servlet,以及具体处理Request请求;管理Servlet生命周期,调用Servlet相关方法,处理业务逻辑。
  6. Jasper即为jsp的解析引擎。主要讲jsp文件转换为java文件。并且编译成.class文件。
  7. Naming即为命名服务,将名称和对象连接起来,使我们可以用名称去访问对象。
  8. Session负责创建和管理Session以及Session的持久化,可以自定义。还支持Session集群。底层既是tomcat在服务器开辟的内存空间。可以存放一些临时信息。
  9. Logging主要负责记录相关的日志。包含访问错误信息,以及运行信息。
  10. Jmx javase定义的一些技术规范。 为应用程序、设备、系统植入管理功能的一个框架。通过Jmx可以远程监控tomcat

三.Tomcat核心组件

Connector:接收客户端连接、加工处理客户端请求。

Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。

因此,我们可以把Connector分为四个方面进行理解:

(1)Connector如何接受请求的?
(2)如何将请求封装成Request和Response的?
(3)封装完之后的Request和Response如何交给Container进行处理的?
(4)Container处理完之后如何交给Connector并返回给客户端的?

首先看一下Connector的结构图(图B),如下所示:
在这里插入图片描述Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。

其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。

(1)Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。
(2)Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的,而Processor用来实现HTTP协议的,Adapter将请求适配到Servlet容器进行具体的处理。
(3)Endpoint的抽象实现AbstractEndpoint里面定义的Acceptor和AsyncTimeout两个内部类和一个Handler接口。Acceptor用于监听请求,AsyncTimeout用于检查异步Request的超时,Handler用于处理接收到的Socket,在内部调用Processor进行处理。

至此,我们应该很轻松的回答(1)(2)(3)的问题了,但是(4)还是不知道,那么我们就来看一下Container是如何进行处理的以及处理完之后是如何将处理完的结果返回给Connector的?

Container:所有子容器的父接口、责任链设计模式。
在这里插入图片描述

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

在这里插入图片描述Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。

我们访问应用Context的时候,如果是ROOT下的则直接使用域名就可以访问,例如:www.qi-bb.club,如果是Host(webapps)下的其他应用,则可以使用http://www.qi-bb.club/docs进行访问,当然默认指定的根应用(ROOT)是可以进行设定的,只不过Host站点下默认的主营用是ROOT目录下的。

四.Server处理Http请求

在这里插入图片描述

假设来自客户的请求为:http://localhost:8080/test/index.jsp 请求被发送到本机端口8080

  1. 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
  2. Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
  3. Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
  4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“”的Context去处理)。
  5. path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URLPATTERN为*.jsp的Servlet,对应于JspServlet类。
  6. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。
  7. Context把执行完之后的HttpServletResponse对象返回给Host。
  8. Host把HttpServletResponse对象返回给Engine。
  9. Engine把HttpServletResponse对象返回Connector。
  10. Connector把HttpServletResponse对象返回给客户Browser。

参考资源:
https://blog.csdn.net/jsj13263690918/article/details/80368757
https://www.cnblogs.com/small-boy/p/8042860.html

发布了215 篇原创文章 · 获赞 135 · 访问量 114万+

猜你喜欢

转载自blog.csdn.net/weinichendian/article/details/103826703