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

介绍

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

概述

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

连接器启动以后会启动一组线程用于不同阶段的请求处理过程。

<李>

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

<李>

轮询器线程组。用于监听插座事件,当插座可读或可写等等时,将套接字封装一下添加到工人线程池的任务队列中。

<李>

工人线程组。用于对请求进行处理,包括分析请求报文并创建请求对象,调用容器的管道进行处理。

受体,轮询器,工人所在的ThreadPoolExecutor都维护在NioEndpoint中。

连接器Init和启动

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

<李>

initServerSocket(),通过ServerSocketChannel.open()打开一个考察一下,默认绑定到8080端口,默认的连接等待队列长度是100年,当超过100个时会拒绝服务。我们可以通过配置conf/服务器。xml中连接器的acceptCount属性对其进行定制。

<李>

createExecutor()用于创建工人线程池。默认会启动10个工人线程,Tomcat处理请求过程中,锅最多不超过200个。我们可以通过配置conf/服务器。xml中连接器的minSpareThreads和maxThreads对这两个属性进行定制。

<李>

Pollor用于检测已就绪的插座。默认最多不超过2个,Math.min (2, Runtime.getRuntime () .availableProcessors());。我们可以通过配置pollerThreadCount来定制。

<李>

受体用于接受新连接。默认是1个。我们可以通过配置acceptorThreadCount对其进行定制。

请求过程

受体

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

<李>

受体在启动后会阻塞在ServerSocketChannel.accept ();方法处,当有新连接到达时,该方法返回一个 SocketChannel。

  • 配置完 Socket 以后将 Socket 封装到 NioChannel 中,并注册到 Poller,值的一提的是,我们一开始就启动了多个 Poller 线程,注册的时候,连接是公平的分配到每个 Poller 的。NioEndpoint 维护了一个 Poller 数组,当一个连接分配给 pollers[index] 时,下一个连接就会分配给 pollers[(index+1)%pollers.length].

  • addEvent() 方法会将 Socket 添加到该 Poller 的 PollerEvent 队列中。到此 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 进行处理。

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