Tomcat 启动的基本过程和处理请求的详细过程

tomcat init(init Bootstrap)
        1. define classLoader
        2. Bootstrap.setAwait(true)
        3. Digester for EngineConfig/HostConfig/ContextConfig
        4. reconfigureStartStopExecutor
        5. Bootstrap init
    
tomcat start(Deployment)
        1. StandardHost Start(StandardContext/findChildren())
        2. HostConfig Start(webapps)
        3. StandardEngine and StandardContext  start
        4. MapperListener(StandardContext for Mapper)
        5. add CatalinaShutdownHook 
        
Context Start(start StandardContext)
        1. StandardRoot.resourceStart() 
        2. StardardContext.config(all web.xml、Servlet、Filter、Listener、WEB-INF/*)
        2. StardardContext.setConfigured(true)
        
Background process
        1. 处理Servlet 引擎中的周期性事件
        2. 实现reload功能

Connector Init and Start
        1. initServerSocket()
        2. createExecutor() :Worker、Poller、Acceptor
        
Connector Requtst Process
        Acceptor:
        1. Acceptor 在启动后会阻塞在 ServerSocketChannel.accept(); 方法处,当有新连接到达时,该方法的NioChannel返回一个 SocketChannel。(请求接受成功)
        2. 配置完 Socket 以后将 Socket 封装到 NioChannel 中,并注册到 Poller。
        3. Poller.addEvent() 方法会将 Socket 添加到该 Poller 的 PollerEvent 队列中。到此 Acceptor 的任务就完成了。(Poller.addEvent() 到 EPollSelectorImpl)
        Poller:
        4. 当 Poller 启动后因为 selector 中并没有已注册的 Channel,所以当执行到该方法时只能阻塞。所有的 Poller 共用一个 Selector,其实现类是 sun.nio.ch.EPollSelectorImpl
        5. 通过 addEvent() 方法添加到事件队列中的 Socket 注册到 EPollSelectorImpl ,当 Socket 可读时,Poller 才对其进行处理
        6. createSocketProcessor() 方法将 Socket 封装到 SocketProcessor 中,SocketProcessor 实现了 Runnable 接口。worker 线程通过调用其 run() 方法来对 Socket 进行处理。
        7. execute(SocketProcessor) 方法将 SocketProcessor 提交到线程池,放入线程池的 workQueue 中。workQueue 是 BlockingQueue 的实例。到此 Poller 的任务就完成了。(execute 到 workQueue)
        Worker:
        8. worker 线程被创建以后就执行 ThreadPoolExecutor 的 runWorker() 方法,试图从 workQueue 中取待处理任务,但是一开始 workQueue 是空的,所以 worker 线程会阻塞在 workQueue.take() 方法。
        9. 当新任务添加到 workQueue后,workQueue.take() 方法会返回一个 Runnable,通常是 SocketProcessor,然后 worker 线程调用 SocketProcessor 的 run() 方法对 Socket 进行处理。
        10. createProcessor() 会创建一个 Http11Processor, 它用来解析 Socket,将 Socket 中的内容封装到 Request 中。
        11. postParseRequest() 方法封装一下 Request,并处理一下映射关系(从 URL 映射到相应的 Host、Context、Wrapper)。
        12. connector.getService().getContainer().getPipeline().getFirst().invoke() 会将请求传递到 Container 处理,当然了 Container 处理也是在 Worker 线程中执行的,但是这是一个相对独立的模块
        
        13. request.getHost().getPipeline().getFirst().invoke() 先获取对应的 StandardHost,并执行其 pipeline。
        14. request.getContext().getPipeline().getFirst().invoke() 先获取对应的 StandardContext,并执行其 pipeline。
        15. request.getWrapper().getPipeline().getFirst().invoke() 先获取对应的 StandardWrapper,并执行其 pipeline。
        16. StandardWrapperValve.allocate()用来加载并初始化 Servlet
        17. StandardWrapperValve.createFilterChain() 方法会从 StandardContext 中获取到所有的过滤器,然后将匹配 Request URL 的所有过滤器挑选出来添加到 filterChain 中。
        18. StandardWrapperValve.doFilter() 执行过滤链。
        19. 当所有的过滤器都执行完毕后调用 Servlet 的 service() 方法。

内部的引用关系 

请求到达Poller处理,最终是由Processor来进行处理,为了说明这中间过程所涉及的部分,先整理下在tomcat服务的各个组成部分:ProtocolHandler、Endpoint、Endpoint.Handler、Processor

它们之间的引用关系如下

[ProtocolHandler]     <---------   Connector

org.apache.coyote.ProtocolHandler
org.apache.coyote.AbstractProtocol
org.apache.coyote.http11.AbstractHttp11Protocol
org.apache.coyote.http11.AbstractHttp11JsseProtocol
org.apache.coyote.http11.Http11NioProtocol    *

[Endpoint]           <---------   ProtocolHandler(Http11NioProtocol)
 
org.apache.tomcat.util.net.AbstractEndpoint
org.apache.tomcat.util.net.NioEndpoint      *

处理连接数的控制、连接的建立等工作,主要包括Acceptor和Poller两大部分,将建立好的连接交由Endpoint的Handler去处理

[Endpoint.Handler]     <---------   Endpoint(NioEndpoint)

AbstractEndpoint.Handler
     AbstractConnectionHandler    < -- > AbstractProtocol
     Http11ConnectionHandler      < -- >  Http11NioProtocol    *

缓存连接和Processor的关系,根据连接寻找Processor来处理

[Processor]      <---------   Endpoint.Handler

org.apache.coyote.Processor
org.apache.coyote.AbstractProcessor
org.apache.coyote.http11.AbstractHttp11Processor
org.apache.coyote.http11.Http11NioProcessor    *

(process方法)处理http请求中的相关业务,服务状态,协议解析,请求握手,内容解压等,构造适合Adapter处理request和response对象,然后调用Adater进行业务数据处理。

Acceptor和Poller都是属于Endpoint的内部组成部分,所以,这里是socket连接有数据到达时,被交到Endpoint.Handler中,经过缓存加速,找到对应的Processor之后,交由Processor来处理。

Processor处理完http协议相关的内容后,交由Adapter来处理业务。

Tomcat start and process相关推荐

  1. [置顶] 将项目从tomcat 迁移到JBoss

    注:针对的是jboss5.0,其它版本没有测试过 ,主要参考了:http://www.diybl.com/course/3_program/java/javajs/20100719/460908.ht ...

  2. 17102101_CentOS7下利用systemd机制实现tomcat开机自启动

    在之前的博文中已经对CentOS7下利用init.d目录下创建开机启动服务脚本,实现tomcat开机启动的介绍.但作为CentOS7来说,通过init.d建立启动脚本的机制已经不被推荐,推荐的方式是利 ...

  3. centos 安装java web_Centos上安装java web的环境

    Centos上安装java web的环境 ,本次例子尽量不用yum形式安装(因为我不知道yum安装怎么指定目录,想把java,tomcat,mysql安装到指定的文件夹下,好管理). (java和to ...

  4. 遇到的问题及解决方法

    系统页面显示错误 时间:2018年7月10日 问题描述:将构建好的项目同步到客户运行环境中,同步完成重启tomcat打开页面显示这错误 解决方法:将运行服务器的时间进行校准后,解决问题. 服务启动错误 ...

  5. tomcat7.027-webSocket应用程序构建01

    前几天研究了一下tomcat7.027的webSocket实现.简单看了下官方源码自己实践了一下. 在这里简单介绍一下tomcat的webSocketAPI使用. 在这里啰嗦几句:[ 很多朋友听说we ...

  6. Spring Boot Actuator [监控与管理]

    1. 如何添加 2. actuator 的原生端点(API) 2.1 应用类配置 2.1.1 http://localhost:8080/actuator/conditions 2.1.2 http: ...

  7. Spring Boot Actuator 端点监控

    spring-boot-starter-actuator库主要用来暴露自身信息.有助于对应用程序进行监控和管理,以及采集一些应用指标.actuator通过 restful api 请求来监管.审计.收 ...

  8. Jboss与jdk版本不兼容问题

    环境背景: JDK环境:1.7 Jboss:4.2.0.1 问题背景: EJB发布webserivce已经成功,能够成功访问wsdl. 使用axis1自带的sample/client下的类测试,则测试 ...

  9. Spring Boot实战,整合Prometheus实现应用监控

    Micrometer简介 Micrometer 为 Java 平台上的性能数据收集提供了一个通用的 API,应用程序只需要使用 Micrometer 的通用 API 来收集性能指标即可.Microme ...

最新文章

  1. 练习用基础SQL语句
  2. PHP 高级编程之多线程
  3. 【PC工具】传说中最好的编程手册管理软件Zeal,支持194种编程文档,学习编程语法查阅必备工具...
  4. 服务器强迫患者 ;软件试用狂人
  5. 使用ILmerge合并Exe、Dll文件的帮助类
  6. BurpSuite技巧之二重代理
  7. MYSQL数据库安装记
  8. 方法range作用于对象worksheet时失败_VB.NET Excel操作类(获取工作簿列表和工作表列表及工作表对象)...
  9. 2)Java中的==和equals
  10. 蚂蚁金服:开源增强版 SpringBoot 的研发框架!
  11. 手机号码校验、邮箱校验
  12. linux windows下重启oracle
  13. 微博开发笔记上(未完待续)
  14. Oracle 客户端工具介绍
  15. java long精度问题_解决Long类型超过16位丢失精度问题的两种方法
  16. Java代理模式详解
  17. 查询水果价格(PTA-武理-C实验)
  18. 第三章课后习题重点内容
  19. CNSD在这里记录自己成长
  20. 稳定智能的在线考试系统

热门文章

  1. mysql8对gis的支持
  2. mysql服务器手册_MySQL手册
  3. 计算机标准差的按键是什么,在计算器上用标准差键直接求离均差平方和的方法...
  4. No 和 Not 的区别
  5. ModuleNotFoundError: No module named sklearn
  6. 实验2:天气查询小程序
  7. 一级域名和二级域名的差异
  8. c语言求三个整数的积,反汇编学习-C语言实例解析精粹-实例3求整数之积
  9. prev_permutation函数
  10. 想一想就感觉到生活还是充满很多正能量的