前面摆了三节的姿势,现在终于要看到最终tomcat监听端口,接收请求了。

目录

  • Connector
  • Http11Protocol
  • JIoEndpoint
  • 总结

在前面的初始化都完成之后,进行Connector的初始化,也是执行一些生命周期方法。

Connector

在启动过程中这个类的主要作用是初始化并启动CoyoteAdapter和Http11Protocol:

initInternal

  • 新建一个CoyoteAdapter,并调用protocolHandler.setAdapter方法设置adapter(最后protocol创建processor处理完成之后会调用adapter.service方法)
  • 初始化protocolHandler(在Connector构造函数中就获得了该实例),实际调用的是超类的init方法
  • 初始化mapperListener

startInternal

作用很简单了

  • 启动protocolHandler
  • 启动mapperListener

Http11Protocol

前面在第一节中说到Connector的时候绘制了tomcat中关于协议的类图,对于不同的协议有不同的连接器,这里主要说关于http11的,ajp也类似。这个类的主要作用就是启动一个JIoEndpoint)(其内部类Acceptor是最终启动线程接收请求的类)。

特别需要关注的是该构造函数:

  • new JIoEndpoint()
  • new Http11ConnectionHandler(),这个类是Http11Protocol的内部类,负责获取processor来处理请求
  • ((JIoEndpoint)endpoint).setHandler设置endpoint中handler

init

虽然是Http11Protocol的实例,但是执行的是父类的init方法,主要的操作在父类的父类的init方法中AbstractProtocol.init

  • 注册MBean
  • 调用JIoEndpoint.init(该类在)初始化JIoEndpoint

start

  • endpoint.start()启动JIoEndpoint

JIoEndpoint

来到了tomcat启动的最后一站,要启动线程监听端口接收请求了。继承关系

所以也用到了很多父类的方法,这个的作用就是新建socket,绑定到对应端口

绑定到端口之后,就可以调用socket.accept()接受请求了

所以startInternal方法主要进行了一下操作

  • 如果Executor(用来执行processor线程)为null则新建
  • 启动Acceptor线程,接受请求就在这个线程里面
  • 启动一个请求超时检测线程JIoEndpoint$AsyncTimeout
protected class Acceptor extends AbstractEndpoint.Acceptor {

    @Override
public void run() { int errorDelay = 0; // Loop until we receive a shutdown command
while (running) { // Loop if endpoint is paused
while (paused && running) {
state = AcceptorState.PAUSED;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// Ignore
}
} if (!running) {
break;
}
state = AcceptorState.RUNNING; try {
//if we have reached max connections, wait
countUpOrAwaitConnection(); Socket socket = null;
try {
// Accept the next incoming connection from the server
// socket
socket = serverSocketFactory.acceptSocket(serverSocket);
} catch (IOException ioe) {
countDownConnection();
// Introduce delay if necessary
errorDelay = handleExceptionWithDelay(errorDelay);
// re-throw
throw ioe;
}
// Successful accept, reset the error delay
errorDelay = 0; // Configure the socket
if (running && !paused && setSocketOptions(socket)) {
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
countDownConnection();
// Close socket right away
closeSocket(socket);
}
} else {
countDownConnection();
// Close socket right away
closeSocket(socket);
}
} catch (IOException x) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), x);
}
} catch (NullPointerException npe) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), npe);
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("endpoint.accept.fail"), t);
}
}
state = AcceptorState.ENDED;
}
}

终于看到梦寐以求的socket.accept了!虽然只是为了最后这一步,tomcat废了这么多周折,作用还是很重要的:

  • 用来管理生命周期的Lifecycle,给这个容器的生命周期提供了规范和基本实现
  • 便于扩展的容器架构,多Host可用来分布式,多Context部署多个webapp,Wrapper用来作为servlet的直接容器(比如如果是SingleThreadModel的话需要有多个servlet实例)
  • 可以处理多种协议的Connector

总结

到这里tomcat 这个启动过程算是完成了,当然了里面还是有很多细节略过了,不过还是很值得仔细进行专题学习,比如:server.xml的解析,web.xml的解析(这样也能明白平时配置的都有什么作用),tomcat的热加载功能是怎么实现的(对的,就在启动过程中启动了一个线程)等等。这些都做了笔记,以后再整理下。

How Tomcat works — 五、tomcat启动(4)的更多相关文章

  1. how tomcat works 五 servlet容器 上

    servlet容器是用来处理请求servlet资源,并为Web客户端填充response对象的模块.在上一篇文章(也就是书的第四章)我们设计了SimpleContainer类,让他实现Containe ...

  2. How Tomcat works — 四、tomcat启动(3)

    上一节说到StandardService负责启动其子组件:container和connector,不过注意,是有先后顺序的,先启动container,再启动connector,这一节先来看看conta ...

  3. How Tomcat Works(十五)

    本文接下来分析Context容器,Context容器实例表示一个具体的Web应用程序,其中包括一个或多个Wrapper实例:不过Context容器还需要其他的组件支持,典型的如载入器和Session管 ...

  4. How Tomcat Works(五)

    本文接下来介绍tomcat的默认连接器,Tomcat中的默认连接器必须满足以下要求: 实现org.apache.catalina.Connector接口 负责创建实现org.apache.catali ...

  5. How Tomcat works — 三、tomcat启动(2)

    在了解了tomcat 的一些基本组件之后,学习启动过程就更容易理解了,因为启动过程就是启动各个组件. 目录 启动顺序 Bootstrap类 Catalina类 StandardServer类和Stan ...

  6. How Tomcat works — 二、tomcat启动(1)

    主要介绍tomcat启动涉及到的一些接口和类. 目录 概述 tomcat包含的组件 server和service Lifecycle Container Connector 总结 概述 tomcat作 ...

  7. How Tomcat Works(十八)

    在前面的文章中,如果我们要启动tomcat容器,我们需要使用Bootstrap类来实例化连接器.servlet容器.Wrapper实例和其他组件,然后调用各个对象的set方法将它们关联起来:这种配置应 ...

  8. How Tomcat Works(十七)

    在前面的文章中,已经学会了如何通过实例化一个连接器和容器来获得一个servlet容器,并将连接器和容器相关联:但在前面的文章中只有一个连接器可用,该连接器服务8080端口上的HTTP请求,无法添加另一 ...

  9. How Tomcat Works(十三)

    本文分析tomcat容器的安全管理,servlet技术支持通过配置部署描述器(web.xml文件)来对受限内容进行访问控制:servlet容器是通过一个名为验证器的阀来支持安全限制的,当servlet ...

随机推荐

  1. FZU 1894 志愿者选拔 (单调队列)

    /****************************************************************** 题目: 志愿者选拔(FZU 1894) 算法: 单调队列 算法思 ...

  2. 用PHP将Unicode 转化为UTF-8

    function unescape($str) { $str = rawurldecode($str); preg_match_all("/(?:%u.{4})|&#x.{4};|& ...

  3. DSS中间件介绍

    DSS中间件采用HTTP协议,终端可以是任何的支持Http协议的设备,开发工具和语言均不受限制 DMS消息服务, 采用类似HTTP的协议 DSS-API介绍(持续更新) http://www.dioc ...

  4. [VBS]关机恶作剧

    一.关于脚本 1)本文中的脚本完成以下功能: 随机生成3道二位数加法题,如果答题错误则在60秒后关机. 如果全答对了,也会在60后关机,但脚本会提示解除定时关机的办法 2)在脚本运行过程中,退出本脚本 ...

  5. js学习---常用的内置对象(API)小结 :

    内置对象(API): 日期 Date: getFullYear() 返回完整的4位的年份  如:2016 getMonth()    返回月份,从0开始 getDate()   返回当前月的第几天,当 ...

  6. [UE4]武器碰撞

    实现武器战斗伤害系统,击中时如何发出碰撞事件产生伤害,目前探索的有通过物理碰撞和LineTrace两种方法. 物理碰撞通过Overlap事件的方法,优点是易于实现,缺点是无法具体到碰撞骨骼位置,低帧数 ...

  7. 6.5 为什么Android用Java不用c实现?

    C/C++过于底层,开发者要花很多的经历对C/C++的语言研究清楚,例如C/C++的内存机制,如果稍不注意,就会忘了开启或者释放.而Java的GC会自动处理这些,省去了很多的时间让开发者专注于自己的业 ...

  8. SQLite主键自增需要设置为integer PRIMARY KEY

    按照正常的SQL语句,创建一个数据表,并设置主键是这样的语句: ), EventType )) 但使用这种办法,在SQLite中创建的的数据表,如果使用Insert语句插入记录,如下语句: INSER ...

  9. 跟我一起学WCF(3)——利用Web Services开发分布式应用

    一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...

  10. C#设计模式(17)——观察者模式(Observer Pattern)

    一.引言 在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用.在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题. 二. ...