不少開源應用服務器都是集成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容器性能的關鍵。