天天看点

Tomcat是如何处理一次请求的 源码版本8.0.21

目录

​​1.Tomcat容器构成​​

​​2.Tomcat是如何接收一次请求的​​

1.Tomcat容器构成

Tomcat是如何处理一次请求的 源码版本8.0.21

2.Tomcat是如何接收一次请求的

        从上图可知Tomcat中有很多容器,包括Server、Service、Connector等。其中Connector正是与HTTP请求处理相关的容器。Connector的实现分为以下几种:

  • Http Connector:基于HTTP协议,负责建立HTTP连接。它又分为BIO Http Connector与NIO Http Connector两种,后者提供非阻塞IO与长连接Comet支持。
  • AJP Connector:基于AJP协议,AJP是专门设计用于Tomcat与HTTP服务器通信定制的协议,能提供较高的通信速度和效率。如与Apache服务器集成时,采用这个协议。
  • APR HTTP Connector:用C实现,通过JNI调用的。主要提升对静态资源(如HTML、图片、CSS、JS等)的访问性能。

具体源码实现:setProtocol函数的入参protocol在server.xml中配置

Tomcat是如何处理一次请求的 源码版本8.0.21
Tomcat是如何处理一次请求的 源码版本8.0.21

 setProtocol函数代码作用:主要判断了是否启用Apr模式,如果启用,那么"HTTP/1.1"就将org.apache.coyote.http11.Http11AprProtocol这个类作为Handler,其他协议以此类推。

我们可以看到在关闭Apr模式的时候,配置"HTTP/1.1"是将Http11NioProtocol类作为Handler,Http11NioProtocol为NIO模式连接器,因为NIO模式涉及到生产者消费者模式,代码略复杂,下文我们将用Tomcat7中的Http11Protocol类(BIO模式)来剖析一次请求的过程。

Tomcat是如何处理一次请求的 源码版本8.0.21

可以看到Http11NioProtocol在构造的时候初始化了一个JIoEndpoint(通信端点)

Tomcat是如何处理一次请求的 源码版本8.0.21

在JIoEndpoint类中我们看到其内部类Acceptor启动一个线程,一直在循环接收请求

Tomcat是如何处理一次请求的 源码版本8.0.21

 跟进processSocket方法可以看到用线程池做了一次调用

Tomcat是如何处理一次请求的 源码版本8.0.21

跟进内部run方法下finally块中handler.process(socket, SocketStatus.DISCONNECT);开始调用handler处理请求

Tomcat是如何处理一次请求的 源码版本8.0.21

 继续跟进发现其调用super.process(socket, status);

Tomcat是如何处理一次请求的 源码版本8.0.21
Tomcat是如何处理一次请求的 源码版本8.0.21

最终我们一路跟进发现调用到AbstractHttp11Processor类中 process()方法 

Tomcat是如何处理一次请求的 源码版本8.0.21

在这个方法中我们可以看到,tomcat已经开始对request对象进行赋值。

Tomcat是如何处理一次请求的 源码版本8.0.21

最终将请求交给adapter去处理,

Tomcat是如何处理一次请求的 源码版本8.0.21

 最终调用connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);将请求交给Engine的Pineline处理

Tomcat是如何处理一次请求的 源码版本8.0.21

 最终通过责任链模式,一步步的调用到ApplicationFiterChain执行Servlet的service方法。

Tomcat是如何处理一次请求的 源码版本8.0.21

 最终在HttpServlet类中去调用doGet方法,继而调用到我们继承自HttpServlet自定义的doGet方法。

继续阅读