不少开源应用服务器都是集成tomcat做为web container的,并且对于tomcat的servlet container这部分代码不多改动。这样,这些应用服务器的性能基本上就取决于Tomcat处理HTTP请求的connector模块的性能。本文首先从应用层次分析了tomcat全部的connector种类及用法,接着从架构上分析了connector模块在整个tomcat中所处的位置,最后对connector作了详细的源代码分析。而且咱们以Http11NioProtocol为例详细说明了tomcat是如何经过实现ProtocolHandler接口而构建connector的。web
由上面的介绍咱们能够知道,实现Connector就是实现ProtocolHander接口的过程。tomcat
AjpAprProtocol、AjpProtocol、Http11AprProtocol、Http11Protocol、JkCoyoteHandler、MemoryProtocolHandler这些实现类的实现流程与Http11NioProtocol相同,下面咱们以Http11NioProtocol为类重点说明tomcat中如何实现ProtocolHander接口的。服务器
Http11NioProtocol实现了ProtocolHander接口,它将全部的操做委托给NioEndpoint类去作,以下图:数据结构
NioEndpoint类中的init方法中首先以普通阻塞方式启动了SocketServer:架构
NioEndpoint类的start方法是关键,以下:异步
能够看出,在start方法中启动了两个线程和一个线程池:socket
在Init接口实现方法中阻塞方式启动ServerSocketChannel。性能
Start方法中启动了线程池,acceptor线程与Poller线程。其中acceptor与poller线程通常数目为1,固然,数目也可配置。测试
能够看出,线程池有两种实现方式:线程
在Acceptor线程中接收了客户请求,同时委托线程池注册READ事件。
在setSocketOptions方法中,首先将socket配置成非阻塞模式:
在setSocketOptions方法中,最后调用getPoller0().register(channel);一句为SocketChannel注册READ事件,register方法代码以下(注意:这是Poller线程的方法):
其中attachment的结构以下,它能够看作是一个共享的数据结构:
注意:
NioEndpoint类中的Handler接口定义以下:
其中process方法经过Adapter来调用Servlet Container生成返回结果。Adapter接口定义以下:
实现一个tomcat链接器Connector就是实现ProtocolHander接口的过程。Connector用来接收Socket Client端的请求,经过内置的线程池去调用Servlet Container生成响应结果,并将响应结果同步或异步的返回给Socket Client。在第三方应用集成tomcat做为Web容器时,通常不会动Servlet Container端的代码,那么connector的性能将是整个Web容器性能的关键。