您的位置:首页 > 运维架构 > Tomcat

tomcat 7--connector

2014-01-07 16:07 28 查看
connetor 启动的核心代码:

Connector 从 server.xml 配置中读取属性,Connector 包含 ProtocolHandler 模块 和 Adaptor 模块。

Connetor 也是容器组件,也就是实现了LifecycleMBeanBase 接口。启动入口从startInternal() 方法开始。

connector 启动时,调用 protocolHandler.start(); 启动ProtocolHandler 模块,ProtocolHandler 调用 endpoint.start(); 启动endpoint

1。 ProtocolHandler 模块

ProtocolHandler 接口的 HTTP 协议的实现是 Http11Protocol .

[b]Http11Protocol[/b] 构造函数中初始化 endpointenpoint 的组件handler 。

[b]handler[/b] 是 Http11Protocol 内部类Http11ConnectionHandler 的实例,实现了Handler 接口。

1.1 Http11Protocol

http11protocol 包含 endpoint 模块 ,对应的BIO实现是 JIoEndpoint 。



Http11Protocol 的父类AbstractProtocol 包含JIoEndpoint 的父类AbstractEndpoint ,负责初始化 AbstractEndpoint,设置从 server.xml 读取的属性。

AbstractProtocol 中声明如下:

/**

* Endpoint that provides low-level network I/O - must be matched to the

* ProtocolHandler implementation (ProtocolHandler using BIO, requires BIO

* Endpoint etc.).

*/

protected AbstractEndpoint endpoint = null;

可见 endpoint 是负责处理socket 连接的。JIoEndpoint 实现了父类的 startInternal() 方法。

1.1.1 JIoEndpoint

1. 父类AbstractEndpoint 初始化processor线程池

TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());

executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);

<Tomcat 对于多线程的任务大量应用到了 ThreadPoolExecutor ,之后再研究一下>

2. JIoEndpoint的startInternal() 首先调用上面提到的 父类 创建 processor 线程池 ,这个就是用来处理socket连接的。也就是http 请求的入口

这是一个线程池对象。供Acceptor线程使用,它是由JIodenpoint 持有的成员对象,因此是线程共享的。

启动 Acceptor 线程

JIoEndpoint 类在正式startInternal() 先调用 bind() 方法,设置一些参数,如 启动 Acceptor 线程的个数,acceptorThreadCount=1默认,实例化一个 serverSocketFactory ,用这个工厂创建一个 serverSocket 。

JIoEndpoint
中Acceptor定义如下

protected class Acceptor extends AbstractEndpoint.Acceptor

Accptor 线程类监听socket 代码:

socket = serverSocketFactory.acceptSocket(serverSocket); 实际就是调用了一下 serverSocket.accept() 方法,阻塞 socket I/O,直到接收到输入。

收到socket input ,包装socket,SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);

新建一个 SocketProcessor 加到processor线程池 执行,这个processor 线程池就是之前JIoEndpoint 初始化的 executor对象。

getExecutor().execute(new SocketProcessor(wrapper));

SocketProcessor 是 JIoEndpoint 的内部类 ,是一个实现了runable 接口的command 。command 就是一个任务,这个任务由 基于线程池 的 Executor 任务执行器调用,在这个command 里 调用 handler 处理socket 连接。

state = handler.process(socket, SocketStatus.OPEN);

3.handler 是 JIoEndpoint 持有的



这个Process() 方法在 AbstractConnectionHandler 中实现,AbstractConnectionHandler 也是一个内部类。

AbstractConnectionHandler 有一个缓存 connections,存放 Http11Processor 对象。

先从缓存里根据socket作为key ,缓存没有这个socket的记录就回收一个,回收也没有就实例化一个新的 Http11Processor 对象



Http11ConnectionHandler维护了一个Http11Processor对象池,父类AbstractConnectionHandler 的
process() 方法处理socket连接,如下:

1.这个对象池是由 ConcurrentHashMap 实现的。先取出这个Http11Processor对象,没有则创建一个

Processor<S> processor = connections.remove(socket.getSocket());
if (processor == null) {
                    processor = createProcessor();
                }


2.调用Http11Processor父类 AbstractHttp11Processor 方法处理socket,

state = processor.process(socket);

3. 按照Tomcat 之前 Jioendpoint 组件持有Http11ConnectionHandler 组件,Http11ConnectionHandler组件持有Http11Processor
组件的思路,

Http11Processor 也持有
Adaptor
组件。它的父类 AbstractProcessor 负责new 一个 request 对象和 response 对象。

process 方法里 调用Adaptor的service() 方法处理http请求。

然后就是传递调用容器的 Valve的invoke ,容器Valve的调用规则就是一个一个从最高级的容器 service 容器绑定的valve 开始向下调子容器的valve,最后调用的Valve就是 StandardWrapperValve, StandardWrapperValve 默认 valve.isAsyncSupported() 返回 true ;

这个Valve的invoke方法将调用servlet 实例:

首先调用过滤器链处理

1、 filterChain.doFilter(request.getRequest(), response.getResponse());

2、filterChain 是递归调用filterChain 的,首先从第一个filter开始,一直到最后一个filter,最后一个filter处理之后,紧接着就是调 servlet 处理了,servlet 处理完之后再 一层层从filter的递归中返回。

servlet.service(request, response);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: