Tomcat最底层是使用Socket来进行链接的,而Connector的做用就是将接受到的请求转换为Request和Response。Request和Response是按照HTTP协议来封装的,封装完成后就交给Container进行处理。Container处理完成后又返回给Connector,由Connector返给客户端前端
Connector主要是经过ProtocolHandler来处理请求的。不用的ProtocolHandler表明不一样的链接类型。例如Http11Protocal使用普通的socket(同步处理),http11NioProtocal使用的NioSocket来连接。ProtocolHandler里面有3个很重要的组件:java
<!-- 定义一个Connector,在8080端口箭头HTTP的请求 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 定义一个Connector,在8009端口箭头AJP的请求 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
在server.xml中就有Connector的配置。图中配置了监听HTTP请求和AJP请求apache
ProtocolHandler有一个抽象实现类AbstractProtocal,下面有3个子类,分别是对Ajp,Http,spdy协议的实现服务器
在Connector中默认是使用org.apache.coyote.http11.Http11NioProtocol。app
Endpoint用于处理具体的链接和数据传输,实现是比较复杂的。NioEndpoint集成AnstractEndpoint,AnstractEndpoint也是一个模板类,例如start()方法在AnstractEndpoint中,其中bind()方法由子类去实现socket
public final void start() throws Exception { if (bindState == BindState.UNBOUND) { bind(); bindState = BindState.BOUND_ON_START; } startInternal(); } public abstract void bind() throws Exception;
NioEndpoint的bind()方法就是初始化ServerSocketChannel和Selectorgoogle
public void bind() throws Exception { serverSock = ServerSocketChannel.open(); socketProperties.setProperties(serverSock.socket()); InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort())); serverSock.socket().bind(addr,getBacklog()); serverSock.configureBlocking(true); //mimic APR behavior serverSock.socket().setSoTimeout(getSocketProperties().getSoTimeout()); // Initialize thread count defaults for acceptor, poller if (acceptorThreadCount == 0) { // FIXME: Doesn't seem to work that well with multiple accept threads acceptorThreadCount = 1; } if (pollerThreadCount <= 0) { //minimum one poller thread pollerThreadCount = 1; } stopLatch = new CountDownLatch(pollerThreadCount); // Initialize SSL if needed initialiseSsl(); selectorPool.open(); }
启动是在startInternal()方法中,主要作了2个事情,初始化Poller线程和Accept线程,Accept负责接收Socket请求,而后具体的处理方法是在Poller线程中。(Accept和Poller是内部类)spa
public void startInternal() throws Exception { if (!running) { running = true; paused = false; processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getProcessorCache()); eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getEventCache()); nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getBufferPool()); // Create worker collection if ( getExecutor() == null ) { createExecutor(); } initializeConnectionLatch(); // Start poller threads pollers = new Poller[getPollerThreadCount()]; for (int i=0; i<pollers.length; i++) { pollers[i] = new Poller(); Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i); pollerThread.setPriority(threadPriority); pollerThread.setDaemon(true); pollerThread.start(); } startAcceptorThreads(); } }
主要用于处理应用层协议(如HTTP),分别由3个基本协议对应3个基本的抽象类线程
Adapter只有一个实现类,就是CoyoteAdapter类。code