How Tomcat works — 五、tomcat启动(4)
前面摆了三节的姿势,现在终于要看到最终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)的更多相关文章
- how tomcat works 五 servlet容器 上
servlet容器是用来处理请求servlet资源,并为Web客户端填充response对象的模块.在上一篇文章(也就是书的第四章)我们设计了SimpleContainer类,让他实现Containe ...
- How Tomcat works — 四、tomcat启动(3)
上一节说到StandardService负责启动其子组件:container和connector,不过注意,是有先后顺序的,先启动container,再启动connector,这一节先来看看conta ...
- How Tomcat Works(十五)
本文接下来分析Context容器,Context容器实例表示一个具体的Web应用程序,其中包括一个或多个Wrapper实例:不过Context容器还需要其他的组件支持,典型的如载入器和Session管 ...
- How Tomcat Works(五)
本文接下来介绍tomcat的默认连接器,Tomcat中的默认连接器必须满足以下要求: 实现org.apache.catalina.Connector接口 负责创建实现org.apache.catali ...
- How Tomcat works — 三、tomcat启动(2)
在了解了tomcat 的一些基本组件之后,学习启动过程就更容易理解了,因为启动过程就是启动各个组件. 目录 启动顺序 Bootstrap类 Catalina类 StandardServer类和Stan ...
- How Tomcat works — 二、tomcat启动(1)
主要介绍tomcat启动涉及到的一些接口和类. 目录 概述 tomcat包含的组件 server和service Lifecycle Container Connector 总结 概述 tomcat作 ...
- How Tomcat Works(十八)
在前面的文章中,如果我们要启动tomcat容器,我们需要使用Bootstrap类来实例化连接器.servlet容器.Wrapper实例和其他组件,然后调用各个对象的set方法将它们关联起来:这种配置应 ...
- How Tomcat Works(十七)
在前面的文章中,已经学会了如何通过实例化一个连接器和容器来获得一个servlet容器,并将连接器和容器相关联:但在前面的文章中只有一个连接器可用,该连接器服务8080端口上的HTTP请求,无法添加另一 ...
- How Tomcat Works(十三)
本文分析tomcat容器的安全管理,servlet技术支持通过配置部署描述器(web.xml文件)来对受限内容进行访问控制:servlet容器是通过一个名为验证器的阀来支持安全限制的,当servlet ...
随机推荐
- C++队列中应该注意的一些问题
第一次在C++中写类,新手,见笑 #include<iostream.h>#include<iostream>template<typename T> class ...
- UIButton的常用属性
可以通过代码的方式创建UIButton 通用实例化对象方法: UIButton *button = [[UIButton alloc] initWithFrame:rect]; 快速实例化对象方法: ...
- CSS颜色名称和颜色值
aliceblue:艾利斯兰 #F0F8FF antiquewhite:古董白 #FAEBD7 aqua:浅绿色 #00FFFF aquamarine:碧绿色 #7FFFD4 azure:天蓝色 #F ...
- Delphi初学者,向万一老师致敬
今天首开博客园... 刚开始学习Delphi难免诸多不懂... 感谢万能的万一老师...
- 图片大小的模式UIViewContentMode
- Android 隐藏软键盘方法
第一种:public static void hideInput(Activity activity) { View curFoc = activity.getCurrentFocus(); if ( ...
- DevExpress组件之——PopupMenu组件(转)
出处:http://www.cnblogs.com/xlx0210/archive/2010/07/14/1777366.html 目录在项目中使用了第三方控件DevExpress,得开始研究其他控件 ...
- tomcat 虚拟主机配置
1.虚拟主机 服务器接收到客户端请求时,会根据HTTP请求报文中的HOST头选择web站点进行响应.发送请求时,url中的主机名会被作为HTTP请求报文中的HOST发送给服务器.因此,可以根据不同的H ...
- 如何将jar包加入到Maven本地仓库
原则上Maven的设计是不需要这么做的,因为pom.xml中依赖的jar包会自动实现从中央仓库下载到本地仓库.但是公司设计了一个setting,如果本地仓库没有,就去setting指定的url中下载j ...
- Android--UI
1.layout_width 属性和 layout_height 属性:Android中所有的控件都包含这两个属性,有三种可选值 match_parent, fill_parent, wrap_con ...