java 调用tomcat api,tomcat处理http请求-下

很多开源应用服务器都是集成tomcat作为web container的,而且对于tomcat的servlet container这部分代码很少改动。这样,这些应用服务器的性能基本上就取决于Tomcat处理HTTP请求的connector模块的性能。本文首先从应用层次分析了tomcat所有的connector种类及用法,接着从架构上分析了connector模块在整个tomcat中所处的位置,最后对connector做了详细的源代码分析。并且我们以Http11NioProtocol为例详细说明了tomcat是如何通过实现ProtocolHandler接口而构建connector的。

4 如何实现Connector

由上面的介绍我们可以知道,实现Connector就是实现ProtocolHander接口的过程。

AjpAprProtocol、AjpProtocol、Http11AprProtocol、Http11Protocol、JkCoyoteHandler、MemoryProtocolHandler这些实现类的实现流程与Http11NioProtocol相同,下面我们以Http11NioProtocol为类重点说明tomcat中如何实现ProtocolHander接口的。

Http11NioProtocol实现了ProtocolHander接口,它将所有的操作委托给NioEndpoint类去做,如下图:

p_w_picpath1.jpg

p_w_picpath2.jpgNioEndpoint类中的init方法中首先以普通阻塞方式启动了SocketServer:

NioEndpoint类的start方法是关键,如下:

p_w_picpath3.jpg

可以看出,在start方法中启动了两个线程和一个线程池:Acceptor线程,该线程以普通阻塞方式接收客户端请求(socket.accep()),将客户Socket交由线程池是处理,线程池要将该Socket配置成非阻塞模式(socket.configureBlocking(false)),并且向Selector注册READ事件。该线程数目可配置,默认为1个。

Poller线程,由于Acceptor委托线程为客户端Socket注册了READ事件,当READ准备好时,就会进入Poller线程的循环,Poller线程也是委托线程池去做,线程池将NioChannel加入到ConcurrentLinkedQueue队列中。该线程数目可配置,默认为1个。

线程池,就是上面说的做Acceptor与Poller线程委托要做的事情。

4.1 Init接口实现方法中阻塞方式启动ServerSocketChannel

在Init接口实现方法中阻塞方式启动ServerSocketChannel。

p_w_picpath4.jpg

4.2 Start接口实现方法中启动所有线程

Start方法中启动了线程池,acceptor线程与Poller线程。其中acceptor与poller线程一般数目为1,当然,数目也可配置。

p_w_picpath5.jpg

可以看出,线程池有两种实现方式:普通queue + wait + notify方式,默认使用的方式,据说实际测试这种比下种效率高

JDK1.5自带的线程池方式

4.3 Acceptor线程接收客户请求、注册READ事件

在Acceptor线程中接收了客户请求,同时委托线程池注册READ事件。在Acceptior线程中接收了客户请求(serverSock.accept())

p_w_picpath6.jpg

委托线程池处理

p_w_picpath7.jpg

在线程池的Worker线程的run方法中有这么几句:

p_w_picpath8.jpg

在setSocketOptions方法中,首先将socket配置成非阻塞模式:

p_w_picpath9.jpg

在setSocketOptions方法中,最后调用getPoller0().register(channel);一句为SocketChannel注册READ事件,register方法代码如下(注意:这是Poller线程的方法):

p_w_picpath10.jpg

其中p_w_upload的结构如下,它可以看做是一个共享的数据结构:

p_w_picpath11.jpg

4.4 Poller线程读请求、生成响应数据、注册WRITE事件在上面说的setSocketOptions方法中调用Poller线程的register方法注册读事件之后,当READ准备就绪之后,就开始读了。下面代码位于Poller线程的run方法之中:

p_w_picpath12.jpg

可以看到,可读之后调用processSocket方法,该方法将读处理操作委拖给线程池处理(注意此时加入到线程池的是NioChannel,不是SocketChannel):

p_w_picpath13.jpg

线程池的Worker线程中的run方法中的部分代码如下(请注意handler.process(socket)这一句):

p_w_picpath14.jpg

注意:调用了hanler.process(socket)来生成响应数据)

数据生成完之后,注册WRITE事件的,代码如下:

p_w_picpath15.jpg

4.5 Handle接口实现类通过Adpater调用Servlet容器生成响应数据

NioEndpoint类中的Handler接口定义如下:

p_w_picpath16.jpg

其中process方法通过Adapter来调用Servlet Container生成返回结果。Adapter接口定义如下:

p_w_picpath17.jpg

4.6 小结

实现一个tomcat连接器Connector就是实现ProtocolHander接口的过程。Connector用来接收Socket Client端的请求,通过内置的线程池去调用Servlet Container生成响应结果,并将响应结果同步或异步的返回给Socket Client。在第三方应用集成tomcat作为Web容器时,一般不会动Servlet Container端的代码,那么connector的性能将是整个Web容器性能的关键。

================================================================================ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================================================ Apache Tomcat Version 8.0.15 Release Notes ========= CONTENTS: ========= * Dependency Changes * API Stability * Bundled APIs * Web application reloading and static fields in shared libraries * Security manager URLs * Symlinking static resources * Viewing the Tomcat Change Log * Cryptographic software notice * When all else fails =================== Dependency Changes: =================== Tomcat 8.0 is designed to run on Java SE 7 and later. ============== API Stability: ============== The public interfaces for the following classes are fixed and will not be changed at all during the remaining lifetime of the 8.x series: - All classes in the javax namespace The public interfaces for the following classes may be added to in order to resolve bugs and/or add new features. No existing interface method will be removed or changed although it may be deprecated. - org.apache.catalina.* (excluding sub-packages) Note: As Tomcat 8 matures, the above list will be added to. The list is not c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值