Tomcat9请求处理流程与启动部署过程的示例分析

技术Tomcat9请求处理流程与启动部署过程的示例分析这篇文章主要为大家展示了“Tomcat9请求处理流程与启动部署过程的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下

本文主要向大家展示“Tomcat9请求处理流程和启动部署流程示例分析”,简单易懂,条理清晰,希望能帮大家解惑。让边肖带领大家学习和研究文章《Tomcat9请求处理流程和启动部署流程实例分析》。

Overview

Tomcat9请求处理流程与启动部署过程的示例分析

连接器启动后,将为请求处理的不同阶段启动一组线程。

接受者线程组用于接受新连接,封装新连接,并选择一个轮询器将新连接添加到轮询器的事件队列中。

轮询线程组。用于监视套接字事件,当套接字可读或可写时,等等。封装套接字并将其添加到工作线程池的任务队列中。

工作线程组。用于处理请求,包括分析请求消息和创建请求对象,调用容器的管道进行处理。

接受者、轮询者和工作者所在的线程池执行器在NioEndpoint中维护。

Connector Init and Start

Tomcat9请求处理流程与启动部署过程的示例分析

ServerSocket(),通过ServerSocketChannel.open()打开一个服务器套接字,默认绑定到端口8080,默认连接等待队列长度为100。当超过100个时,服务将被拒绝。我们可以通过在conf/server.xml中配置连接器的acceptCount属性来自定义连接器

CreateExecutor()用于创建工作线程池。默认情况下,将启动10个Worker线程,在Tomcat处理请求期间,最多不会超过200个woker。我们可以通过在conf/server.xml中配置连接器的minSpareThreads和maxThreads来自定义这两个属性

轮询器用于检测就绪套接字。默认情况下不超过2个,math.min (2,runtime.getruntime()。可用处理器());我们可以通过配置pollerThreadCount对其进行自定义。

接受者用于接受新的连接。默认值为1。我们可以通过配置acceptorThreadCount对其进行自定义。

Request Process

Acceptor

Tomcat9请求处理流程与启动部署过程的示例分析

启动后,接受者将在ServerSocketChannel.accept()中阻止;方法,该方法在新连接到达时返回一个SocketChannel。

配置完套接字后,将套接字打包到NioChannel中,并将其注册到Poller。其价值在于,我们在开始时启动了许多轮询器线程,当注册时,连接被公平地分配给每个轮询器。NioEndpoint维护一组轮询器。当一个连接被分配给轮询器[index]时,下一个连接将被分配给轮询器[(index 1)% poller . length]。

addEvent()方法将套接字添加到此轮询器的轮询中。

nt 队列中。到此 Acceptor 的任务就完成了。

Poller

Tomcat9请求处理流程与启动部署过程的示例分析

  1. selector.select(1000)。当 Poller 启动后因为 selector 中并没有已注册的 Channel,所以当执行到该方法时只能阻塞。所有的 Poller 共用一个 Selector,其实现类是 sun.nio.ch.EPollSelectorImpl

  2. events() 方法会将通过 addEvent() 方法添加到事件队列中的 Socket 注册到 EPollSelectorImpl,当 Socket 可读时,Poller 才对其进行处理

  3. createSocketProcessor() 方法将 Socket 封装到 SocketProcessor 中,SocketProcessor 实现了 Runnable 接口。worker 线程通过调用其 run() 方法来对 Socket 进行处理。

  4. execute(SocketProcessor) 方法将 SocketProcessor 提交到线程池,放入线程池的 workQueue 中。workQueue 是 BlockingQueue 的实例。到此 Poller 的任务就完成了。

Worker

Tomcat9请求处理流程与启动部署过程的示例分析

  • worker 线程被创建以后就执行 ThreadPoolExecutor 的 runWorker() 方法,试图从 workQueue 中取待处理任务,但是一开始 workQueue 是空的,所以 worker 线程会阻塞在 workQueue.take() 方法。

  • 当新任务添加到 workQueue后,workQueue.take() 方法会返回一个 Runnable,通常是 SocketProcessor,然后 worker 线程调用 SocketProcessor 的 run() 方法对 Socket 进行处理。

  • createProcessor() 会创建一个 Http11Processor, 它用来解析 Socket,将 Socket 中的内容封装到 Request 中。注意这个 Request 是临时使用的一个类,它的全类名是 org.apache.coyote.Request,

  • postParseRequest() 方法封装一下 Request,并处理一下映射关系(从 URL 映射到相应的 Host、Context、Wrapper)。

  1. CoyoteAdapter 将 Rquest 提交给 Container 处理之前,并将 org.apache.coyote.Request 封装到 org.apache.catalina.connector.Request,传递给 Container 处理的 Request 是 org.apache.catalina.connector.Request。

  2. connector.getService().getMapper().map(),用来在 Mapper 中查询 URL 的映射关系。映射关系会保留到 org.apache.catalina.connector.Request 中,Container 处理阶段 request.getHost() 是使用的就是这个阶段查询到的映射主机,以此类推 request.getContext()、request.getWrapper() 都是。

  • connector.getService().getContainer().getPipeline().getFirst().invoke() 会将请求传递到 Container 处理,当然了 Container 处理也是在 Worker 线程中执行的,但是这是一个相对独立的模块,所以单独分出来一节。

Container

Tomcat9请求处理流程与启动部署过程的示例分析

  • 需要注意的是,基本上每一个容器的 StandardPipeline 上都会有多个已注册的 Valve,我们只关注每个容器的 Basic Valve。其他 Valve 都是在 Basic Valve 前执行。

  • request.getHost().getPipeline().getFirst().invoke() 先获取对应的 StandardHost,并执行其 pipeline。

  • request.getContext().getPipeline().getFirst().invoke() 先获取对应的 StandardContext,并执行其 pipeline。

  • request.getWrapper().getPipeline().getFirst().invoke() 先获取对应的 StandardWrapper,并执行其 pipeline。

  • 最值得说的就是 StandardWrapper 的 Basic Valve,StandardWrapperValve

  1. allocate() 用来加载并初始化 Servlet,值的一提的是 Servlet 并不都是单例的,当 Servlet 实现了 SingleThreadModel 接口后,StandardWrapper 会维护一组 Servlet 实例,这是享元模式。当然了 SingleThreadModel在 Servlet 2.4 以后就弃用了。

  2. createFilterChain() 方法会从 StandardContext 中获取到所有的过滤器,然后将匹配 Request URL 的所有过滤器挑选出来添加到 filterChain 中。

  3. doFilter() 执行过滤链,当所有的过滤器都执行完毕后调用 Servlet 的 service() 方法。

以上是“Tomcat9请求处理流程与启动部署过程的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/142790.html

(0)

相关推荐

  • java如何简单快速处理 json 中的数据

    技术java如何简单快速处理 json 中的数据java如何简单快速处理 json 中的数据,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。JSONstr.j

    攻略 2021年12月2日
  • 如何使用Hadoop进行分布式并行编程

    技术如何使用Hadoop进行分布式并行编程小编给大家分享一下如何使用Hadoop进行分布式并行编程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧

    攻略 2021年12月4日
  • 七年级上册数学计算题大全,七年级上册数学有理数计算题及答案

    技术七年级上册数学计算题大全,七年级上册数学有理数计算题及答案/tk/showsoft.asp?softid=78603这儿有 [-|98|+76+(-87)]*23[56+(-75)-(7)]-(8+4+3) 5+2

    生活 2021年10月25日
  • VB.NET中子过程和函数怎么用

    技术VB.NET中子过程和函数怎么用小编给大家分享一下VB.NET中子过程和函数怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!VB.NE

    攻略 2021年12月2日
  • k均值算法的基本原理(k均值的算法流程)

    技术K 均值算法是如何让数据自动分组本篇文章给大家分享的是有关K 均值算法是如何让数据自动分组,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。下面要介绍的K

    攻略 2021年12月23日
  • Java基础篇之如何使用日期与时间API技术

    技术Java基础篇之如何使用日期与时间API技术这篇文章主要介绍“Java基础篇之如何使用日期与时间API技术”,在日常操作中,相信很多人在Java基础篇之如何使用日期与时间API技术问题上存在疑惑,小编查阅了各式资料,

    攻略 2021年10月19日